示例#1
0
static int httplive_delete(HTTPLIVE_DATA_T *pLive) {
  char path[VSX_MAX_PATH_LEN];
  char buf[VSX_MAX_PATH_LEN];
  struct stat st;

  httplive_purgetsfiles(pLive, 0xffffffff);

  // 
  // Delete the playlist
  //
  if(snprintf(buf, sizeof(buf), "%s"HTTPLIVE_PL_NAME_EXT, pLive->fileprefix) >= 0) {
    mediadb_prepend_dir(pLive->dir, buf, path, sizeof(path));
    if(fileops_stat(path, &st) == 0 && fileops_DeleteFile(path) != 0) {
      LOG(X_ERROR("Failed to delete '%s'"), path);
    }
  }

  // 
  // Delete any multi-bitrate playlist
  //
  if(snprintf(buf, sizeof(buf), "%s"HTTPLIVE_PL_NAME_EXT, HTTPLIVE_MULTIBITRATE_NAME_PRFX) >= 0) {
    mediadb_prepend_dir(pLive->dir, buf, path, sizeof(path));
    if(fileops_stat(path, &st) == 0 && fileops_DeleteFile(path) != 0) {
      LOG(X_ERROR("Failed to delete '%s'"), path);
    }
  }

  return 0;
}
示例#2
0
int mediadb_mkdirfull(const char *root, const char *path) {

  size_t idxprev;
  struct stat st;
  size_t sz = 0;
  size_t len;
  char buf[VSX_MAX_PATH_LEN];

//  fprintf(stdout, "mkdirfull '%s' '%s'\n", root, path);

  if(!path) {
    return -1;
  }

  if(root) {
    sz = strlen(root);
  }

  buf[sizeof(buf) - 1] = '\0';
  idxprev = sz;
  len = strlen(path);
 
  for(; sz < len && sz < sizeof(buf); sz++) {
    if(path[sz] == DIR_DELIMETER)  {

      memset(buf, 0, sizeof(buf));
      strncpy(buf, path, sz);

//fprintf(stdout, "stat '%s'\n", buf);
      if(strlen(buf) > 0 && fileops_stat(buf, &st) != 0) {
        LOG(X_DEBUG("Creating dir '%s'"), buf);
        if(fileops_MkDir(buf, S_IRWXU | S_IRWXG | S_IRWXO ) < 0) {
          LOG(X_ERROR("Unable to create dir '%s'"), buf);
          return -1;
        }
      }

      while(path[sz] == DIR_DELIMETER) {
        sz++;
      }
      idxprev = sz;
//fprintf(stdout, "after'%s'\n", &path[sz]);
    }
  }
  

  if(sz > idxprev && fileops_stat(path, &st) != 0) {
    LOG(X_DEBUG("Creating dir '%s'"), path);
    if(fileops_MkDir(path, S_IRWXU | S_IRWXG | S_IRWXO ) < 0) {
      LOG(X_ERROR("Unable to create dir '%s'"), path);
      return -1;
    }
  }

  return 0;
}
示例#3
0
char *metafile_find(const char *pathmedia, 
                    char *pathbuf, 
                    unsigned int szpathbuf,
                    int *ploaddefault) {
  int sz;
  struct stat st;
  int loaddefault = 0;

  if(!pathmedia) {
  }

  if(ploaddefault) {
    loaddefault = *ploaddefault;
    *ploaddefault = 0;
  }

  VSX_DEBUG_METAFILE( LOG(X_DEBUG("META - metafile_find pathmedia: '%s', loaddefault: %d"), 
                         pathmedia, loaddefault));

  //
  // Check if the media resource is actually a meta file
  //
  if(metafile_isvalidFile(pathmedia)) {
    return (char *) pathmedia;
  }

  //
  // Try to load the metafile for the media resource
  //
  snprintf(pathbuf, szpathbuf, "%s%s", pathmedia, METAFILE_EXT);
  if(fileops_stat(pathbuf, &st) == 0) {
    return pathbuf; 
  }

  //
  // Try to load the directory wide metafile
  //
  if(loaddefault && (sz = mediadb_getdirlen(pathmedia)) > 0) {
    strncpy(pathbuf, pathmedia, szpathbuf);
    strncpy(&pathbuf[sz], METAFILE_DEFAULT, szpathbuf - sz);
    if(fileops_stat(pathbuf, &st) == 0) {
      if(ploaddefault) {
        *ploaddefault = 1;
      }
      return pathbuf;
    }
  }

  return NULL;
}
示例#4
0
文件: mpd.c 项目: amirsdream/openvcx
static float getMediaRateBps(const MPD_CREATE_CTXT_T *pCtxt, 
                             unsigned int outidx, 
                             const MPD_ADAPTATION_T *pAdaptation) {
  FILE_OFFSET_T size = 0;
  struct stat st;
  float durationSec = 0;
  float rateBps = 0;
  char tmp[256];
  char mediaPath[VSX_MAX_PATH_LEN];

  mpd_format_path(tmp, sizeof(tmp), mpd_format_path_prefix, outidx,
                    pCtxt->init.outfileprefix, pAdaptation->pMedia->mediaUniqIdstr, pCtxt->init.outfilesuffix,
                    pAdaptation->padaptationTag);
  mediadb_prepend_dir(pAdaptation->pMedia->mediaDir, tmp, mediaPath, sizeof(mediaPath));

 if(mediaPath[0] != '\0' && fileops_stat(mediaPath, &st) == 0) {
    size = (FILE_OFFSET_T) st.st_size;
  }

  //LOG(X_DEBUG("GETMEDIARATEBPS mediaPath: '%s', size: %lld"), mediaPath, size);

  if(pAdaptation->pMedia->timescale > 0) {
    durationSec = (float) ((double) pAdaptation->pMedia->duration / pAdaptation->pMedia->timescale);
  }

  if(durationSec > 0) {
    rateBps = 8 * size / durationSec;
  }

  return rateBps;
}
示例#5
0
static int waitForFileContent(MP4_FILE_STREAM_T *pMp4Fs, unsigned int len) {
  //int rc = 0;
  struct stat st;
  FILE_STREAM_T *pFs = (FILE_STREAM_T *) pMp4Fs->pCbData;
  CAP_ASYNC_DESCR_T *pCapCfg = (CAP_ASYNC_DESCR_T *) pMp4Fs->pUserData;
  CAP_HTTP_MP4_T *pCapHttpMp4 = (CAP_HTTP_MP4_T *) pCapCfg->pUserData;
  struct timeval tv0, tv;
  unsigned int rcvTmtMs = pCapHttpMp4->mp4NetStream.rcvTmtMs;

  //fprintf(stderr, "WAIT FOR FILE C PUSERDATA: 0x%x\n", pCapCfg->pUserData);

  gettimeofday(&tv0, NULL);

  while(pFs->offset + len > pFs->size) {

    if(pCapCfg->running != 0 || g_proc_exit) {
      return -1;
    }

    //
    // Check the current file size to see if we have enough content to read
    //
    if(fileops_stat(pFs->filename, &st) != 0) {
      LOG(X_ERROR("Unable to get file size of '%s'."), pFs->filename);
      return -1;
    } else if(st.st_size != pFs->size) {
      pFs->size = st.st_size;
      pMp4Fs->size = pFs->size;
    }

    //
    // If the file does not have enough content to read, sleep and try again
    //
    if(pFs->offset + len > pFs->size) {

      //fprintf(stderr, "waitForFileContent... '%s', offset:%llu, len:%u, size:%llu, sleeping...\n", pFs->filename, pFs->offset, len, pFs->size);

      gettimeofday(&tv, NULL);
      if(TIME_TV_DIFF_MS(tv, tv0) > rcvTmtMs) {
        LOG(X_WARNING("Timeout %u ms exceeded when waiting for frame in '%s'"), 
                      rcvTmtMs, pMp4Fs->cbGetName(pMp4Fs));
        pCapHttpMp4->rcvState.error = MP4_RCV_ERROR_RD_TMT;
        return -1;
      }

      usleep(10000);
    }

  }

  if(pCapCfg->running != 0 || g_proc_exit) {
    return -1;
  }

  return 0;
}
示例#6
0
static int check_filename(const char *filename, 
                          const char *path,
                          META_FILE_T *pMetaFile) {
  int sz;
  struct stat st;

  if(fileops_stat(filename, &st) != 0 && (sz = mediadb_getdirlen(path)) > 0) {
    strncpy(pMetaFile->filestr, path, sizeof(pMetaFile->filestr));
    strncpy(&pMetaFile->filestr[sz], filename, sizeof(pMetaFile->filestr) - sz);
  } else {
    strncpy(pMetaFile->filestr, filename, sizeof(pMetaFile->filestr));
  }

  return 0;
}
示例#7
0
int httplive_init(HTTPLIVE_DATA_T *pLive) {
  struct stat st;
  int rc = 0;

  if(!pLive) {
    return -1;
  }

  pLive->tvNextRoll.tv_sec = 0;
  pLive->tvPriorRoll.tv_sec = 0;
  if(pLive->duration <= 0) {
    pLive->duration = HTTPLIVE_DURATION_DEFAULT;
  }

  if(pLive->fs.fp != FILEOPS_INVALID_FP) {
    CloseMediaFile(&pLive->fs);
  }

  if(fileops_stat(pLive->dir, &st) != 0) {
    LOG(X_ERROR("HTTPLive dir '%s' does not exist."), pLive->dir);
    return -1;
  }

  if(pLive->fileprefix[0] == '\0') {
    strncpy(pLive->fileprefix, HTTPLIVE_TS_NAME_PRFX, sizeof(pLive->fileprefix));
  }

  if(pLive->indexCount == 0) {
    pLive->indexCount = HTTPLIVE_NUM_INDEXES_M3U_DEFAULT;
  } else if(pLive->indexCount < HTTPLIVE_NUM_INDEXES_M3U_MIN) {
    pLive->indexCount = HTTPLIVE_NUM_INDEXES_M3U_MIN;
  } else if(pLive->indexCount > HTTPLIVE_NUM_INDEXES_M3U_MAX) {
    pLive->indexCount = HTTPLIVE_NUM_INDEXES_M3U_MAX;
  }

  httplive_delete(pLive);

  LOG(X_DEBUG("HTTPLive dir: '%s' duration: %.2fs file prefix: '%s'"), 
              pLive->dir, pLive->duration, pLive->fileprefix);

#if defined(HTTPLIVE_INCLUDE_PROGRAM_DATE_TIME) 
  if(s_httplive_tm == 0) {
    s_httplive_tm = time(NULL);
  }
#endif // HTTPLIVE_INCLUDE_PROGRAM_DATE_TIME 

  return rc;
}
示例#8
0
文件: mpd.c 项目: amirsdream/openvcx
int mpd_close(MPD_CREATE_CTXT_T *pCtxt, int deleteFiles, int dealloc) {
  int rc = 0;
  unsigned int idx;
  char mpdpath[VSX_MAX_PATH_LEN];
  int outidx;
  struct stat st;

  if(!pCtxt) {
    return -1;
  }

  if(deleteFiles) {
    //
    // Remove playlist .mpd files
    //
    for(idx = 0; idx < sizeof(pCtxt->mpdOutputTypes) / sizeof(pCtxt->mpdOutputTypes[0]); idx++) {

      for(outidx = -1; outidx < IXCODE_VIDEO_OUT_MAX; outidx++) {

        write_mpd_path(pCtxt, outidx, pCtxt->mpdOutputTypes[idx].type, mpdpath, sizeof(mpdpath));

        if(fileops_stat(mpdpath, &st) == 0 && (rc = fileops_DeleteFile(mpdpath)) != 0) {
          LOG(X_ERROR("Failed to delete '%s'"), mpdpath);
        }
      }

    }
  }

  if(dealloc) {
    for(idx = 0; idx < DASH_MPD_MAX_ADAPTATIONS; idx++) {
      if(pCtxt->segs[idx].pSegments) {
        avc_free((void **) &pCtxt->segs[idx].pSegments);
      }
    }
  }

  return rc;
}
示例#9
0
static int http_mp4_init(CAP_HTTP_MP4_T *pCapHttpMp4) {
  int rc = 0;
  struct stat st;

  if(pCapHttpMp4->rcvState.fStream.filename[0] == '\0') {
    return -1;
  }

  //if((codecfmt_init(&pCapHttpMp4->av, RTMP_TMPFRAME_VID_SZ, RTMP_TMPFRAME_AUD_SZ)) < 0) {
  //  http_mp4_close(pCapHttpMp4);
  //  return -1;
  //}

  if(!(pCapHttpMp4->pMp4FromNet = mp4net_open(pCapHttpMp4))) {
    http_mp4_close(pCapHttpMp4);
    return -1;
  }

  //
  // Delete any prior temporary mp4 file
  //
  if(fileops_stat(pCapHttpMp4->rcvState.fStream.filename, &st) == 0) {
    fileops_DeleteFile(pCapHttpMp4->rcvState.fStream.filename);
  }

  if((pCapHttpMp4->rcvState.fStream.fp = fileops_Open(pCapHttpMp4->rcvState.fStream.filename, 
                                                      O_RDWR | O_CREAT)) == FILEOPS_INVALID_FP) {
    LOG(X_ERROR("Unable to open %s for writing"), pCapHttpMp4->rcvState.fStream.filename);
    http_mp4_close(pCapHttpMp4);
    return -1;
  }

  pCapHttpMp4->rcvState.fStream.offset = 0;
  pCapHttpMp4->rcvState.fStream.size = 0;

  //fprintf(stderr, "VID PQ maxPkts:%d, maxPktLen:%d, grow:%d,%d\n", pCapHttpMp4->client.pQVid->cfg.maxPkts, pCapHttpMp4->client.pQVid->cfg.maxPktLen, pCapHttpMp4->client.pQVid->cfg.growMaxPkts, pCapHttpMp4->client.pQVid->cfg.growMaxPktLen);

  return rc;
}
示例#10
0
int metafile_isvalidFile(const char *path) {
  FILE_STREAM_T fs;
  int rc = 0;
  unsigned char buf[128];
  struct stat st;
  size_t sz;
  size_t idx;
  int is_nl = 0;
  FILE_OFFSET_T fSize;

  if(!path) {
    return 0;
  }

  if(fileops_stat(path, &st) != 0 || (st.st_mode & S_IFDIR)) {
    return 0;
  }

  if(OpenMediaReadOnly(&fs, path) != 0) {
    return 0;
  }

  if((fSize = fs.size) > METAFILE_FILE_CHK_SZMAX) {
    fSize = METAFILE_FILE_CHK_SZMAX;
  }

  while(fs.offset < fSize && rc != 1) {

    sz = sizeof(buf);
    if(fs.offset + sz > fSize) {
      sz = (size_t) (fSize - fs.offset);
    }
    if(ReadFileStream(&fs, buf, sz) != sz) {
      break;
    }
 
    for(idx = 0; idx < sz; idx++) {
      if(!avc_istextchar(buf[idx])) {
        CloseMediaFile(&fs);
        return 0;
      }
      if(buf[idx] == '\n') {
        is_nl = 1;
      } else {
        if(is_nl) {
          if(!memcmp(&buf[idx], METAFILE_KEY_FILE, strlen(METAFILE_KEY_FILE)) || 
             !memcmp(&buf[idx], METAFILE_KEY_DEVICE, strlen(METAFILE_KEY_DEVICE)) ||
             !memcmp(&buf[idx], METAFILE_KEY_TITLE, strlen(METAFILE_KEY_TITLE)) ||
             !memcmp(&buf[idx], METAFILE_KEY_DESCRIPTION, strlen(METAFILE_KEY_DESCRIPTION)) ||
             !memcmp(&buf[idx], METAFILE_KEY_IGNORE, strlen(METAFILE_KEY_IGNORE)) ||
             !memcmp(&buf[idx], METAFILE_KEY_RTMP_PROXY, strlen(METAFILE_KEY_RTMP_PROXY)) ||
             !memcmp(&buf[idx], METAFILE_KEY_RTSP_PROXY, strlen(METAFILE_KEY_RTSP_PROXY)) ||
             !memcmp(&buf[idx], METAFILE_KEY_HTTP_PROXY, strlen(METAFILE_KEY_HTTP_PROXY)) ||
             !memcmp(&buf[idx], METAFILE_KEY_METHODS, strlen(METAFILE_KEY_METHODS)) ||
             !memcmp(&buf[idx], METAFILE_KEY_TOKEN, strlen(METAFILE_KEY_TOKEN)) ||
             !memcmp(&buf[idx], METAFILE_KEY_XCODEARGS, strlen(METAFILE_KEY_XCODEARGS))) {
            rc = 1;
            break;
          } 
        }
        is_nl = 0;
      }
    }

  }

  CloseMediaFile(&fs);

  return rc;
}
示例#11
0
void mediadb_proc(void *parg) {
  MEDIADB_DESCR_T *pMediaDb = (MEDIADB_DESCR_T *) parg;
  struct stat st;
  char buf[VSX_MAX_PATH_LEN];
  const char *avcthumb = NULL;
  size_t sz;
  int rc;
  unsigned int iterIdx = 0;

  if(!pMediaDb->mediaDir) {
    return;
  }

  memset(buf, 0, sizeof(buf));
  sz = mediadb_getdirlen(pMediaDb->dbDir);
  strncpy(buf,  pMediaDb->dbDir, sizeof(buf) - 1);
  buf[sz] = '\0';

  LOG(X_DEBUG("Database dir: '%s'"), pMediaDb->dbDir);

  if(fileops_stat(buf, &st) != 0) {
    //
    // Create database root dir
    //
    LOG(X_DEBUG("Creating dir '%s'"), buf);
    if(fileops_MkDir(buf, S_IRWXU | S_IRWXG | S_IRWXO ) < 0) {
      LOG(X_CRITICAL("Unable to create database dir '%s'"), buf);
      return;
    }
  }

  if(fileops_stat(pMediaDb->dbDir, &st) != 0) {
    //
    // Create database subdir specific for mediaDir
    //
    LOG(X_DEBUG("Creating dir '%s'"), pMediaDb->dbDir);
    if(fileops_MkDir(pMediaDb->dbDir, S_IRWXU | S_IRWXG | S_IRWXO ) < 0) {
      LOG(X_CRITICAL("Unable to create database dir '%s'"), pMediaDb->dbDir);
      return;
    }
  }

  //
  // Check thumbnail creation script
  //
  if(pMediaDb->avcthumb) {

    if(fileops_stat(pMediaDb->avcthumb, &st) == 0) {

      //
      // Truncate the avcthumblog 
      //
      if(pMediaDb->avcthumblog) {
        snprintf(buf, sizeof(buf), DATE_CMD" > %s", pMediaDb->avcthumblog);
        //LOG(X_DEBUG("Executing system command '%s'"), buf);
        rc = system(buf);
        if(fileops_stat(pMediaDb->avcthumblog, &st) != 0) {
          pMediaDb->avcthumblog = NULL;
        }

      }

      if(pMediaDb->lgTnWidth == 0 || pMediaDb->lgTnWidth == 0) {
        pMediaDb->lgTnWidth = LG_THUMB_WIDTH;
        pMediaDb->lgTnHeight = LG_THUMB_HEIGHT;
      }
      if(pMediaDb->smTnWidth == 0 || pMediaDb->smTnHeight == 0) {
        pMediaDb->smTnWidth = SM_THUMB_WIDTH;
        pMediaDb->smTnHeight = SM_THUMB_HEIGHT;
      }

      LOG(X_DEBUG("Using %s to generate thumbnails %dx%d %dx%d"), 
                  pMediaDb->avcthumb,
                  pMediaDb->smTnWidth, pMediaDb->smTnHeight,
                  pMediaDb->lgTnWidth, pMediaDb->lgTnHeight);

    } else {

      LOG(X_WARNING("Unable to find %s  Video thumbnails disabled."), pMediaDb->avcthumb);
      pMediaDb->avcthumb = NULL;
    } 

  } else {
    LOG(X_WARNING("Not using video thumbnails.  Please set '%s=' in the configuration file."),
        SRV_CONF_KEY_AVCTHUMB);
  }

  //
  // Set avchumb to null and do not create thumbnails on first 
  // iteration to allow all avcfidx files to be created quickly
  //
  avcthumb = pMediaDb->avcthumb; 
  pMediaDb->avcthumb = NULL; 
  if(g_proc_exit == 0) {
    iterate_subdirs(pMediaDb, pMediaDb->dbDir, pMediaDb->mediaDir, 1, 0);
    pMediaDb->avcthumb = avcthumb; 
    usleep(2000000);
  }

  while(g_proc_exit == 0) {
    iterate_subdirs(pMediaDb, pMediaDb->dbDir, pMediaDb->mediaDir, 1, iterIdx++);
    usleep(10000000);
  }

}
示例#12
0
static int iterate_subdirs(const MEDIADB_DESCR_T *pMediaDb, const char *pathDb, 
                           const char *pathMedia, int level, unsigned int iterIdx) {
  DIR *pdir;
  FILE_LIST_T fileList;
  FILE_LIST_ENTRY_T *pFileListEntry;
  struct dirent *direntry;
  char bufMedia[VSX_MAX_PATH_LEN];
  char bufDb[VSX_MAX_PATH_LEN];
  char tmpfile[VSX_MAX_PATH_LEN];
  int rc = 0;
  int rcsub = 0;
  int fileListChanged = 0;
  int numTnCreated = 0;
  int highestTn;
  struct stat st;

//fprintf(stdout, "%d dir:'%s' '%s'\n", level, pathDb, pathMedia);

  //
  // TODO: escape invalid chars in pathnames ' , & # $ '
  // 

  if(level >= SRVMEDIA_MAX_LEVELS) {
    LOG(X_WARNING("Path '%s' exceeded max number of subdirs under %s"), 
        pathMedia, pMediaDb->mediaDir);
    return -1;
  }

  if(!(pdir = fileops_OpenDir(pathMedia))) {
    return -1;
  }

  memset(&fileList, 0, sizeof(fileList));
  file_list_read(pathDb, &fileList);
  strncpy(fileList.pathmedia, pathMedia, sizeof(fileList.pathmedia) - 1);


  while((direntry = fileops_ReadDir(pdir)) && g_proc_exit == 0) {
//fprintf(stdout, "- %d %s\n", level, direntry->d_name);
    if(direntry->d_type & DT_DIR) {

      if(mediadb_isvalidDirName(pMediaDb, direntry->d_name)) {

        if(mediadb_prepend_dir(pathDb, direntry->d_name, bufDb, sizeof(bufDb)) < 0) {
          LOG(X_WARNING("Unable to concatenate subdir %s %s"), bufDb, direntry->d_name);
        } else if(mediadb_prepend_dir(pathMedia, direntry->d_name, bufMedia, sizeof(bufMedia)) < 0) {
          LOG(X_WARNING("Unable to concatenate subdir %s %s"), bufMedia, direntry->d_name);
        } else {

          if(numTnCreated > 1) {
            file_list_write(pathDb, &fileList);
          }

          if((rcsub = iterate_subdirs(pMediaDb, bufDb, bufMedia, 
                                      level+1, iterIdx)) < 0) {
            rc = rcsub;
          }
          if(g_proc_exit != 0) {
            break;
          }

        }

      } else if(direntry->d_name[0] != '.') {
        //fprintf(stderr, "skipping directory '%s'\n", direntry->d_name);
      }

    } else if(mediadb_isvalidFileName(pMediaDb, direntry->d_name, 1, 0)) {

//fprintf(stdout, "%d media file %s '%s'\n", level, pathMedia, direntry->d_name);

      if(fileops_stat(pathDb, &st) != 0 && mediadb_mkdirfull(pMediaDb->dbDir, pathDb) < 0) {
        continue;
      } 

      if(mediadb_prepend_dir(pathDb, direntry->d_name, bufDb, sizeof(bufDb)) < 0) {
        LOG(X_ERROR("Unable to concatenate subdir %s %s"), bufDb, direntry->d_name);
        continue;
      } else if(mediadb_prepend_dir(pathMedia, direntry->d_name, bufMedia, sizeof(bufMedia)) < 0) {
        LOG(X_ERROR("Unable to concatenate subdir %s %s"), bufMedia, direntry->d_name);
        continue;
      }

      if(update_fileentry(&fileList, direntry->d_name, bufMedia, &pFileListEntry) > 0) {

        LOG(X_DEBUG("'%s' changed ('%s')"), direntry->d_name, pFileListEntry->name);

        fileListChanged = 1;
        if(pFileListEntry->numTn < 0) {
          pFileListEntry->numTn = 0;
        }

      }

      if(pMediaDb->avcthumb && pFileListEntry && pFileListEntry->vstr[0] != '\0' &&
         pFileListEntry->numTn != -1) {

        //
        // On very first iteration, check all thumbnails
        //
        snprintf(tmpfile, sizeof(tmpfile), "%s%s."NOTN_EXT, bufDb, pMediaDb->tn_suffix);

        if(fileops_stat(tmpfile, &st) == 0 && iterIdx > 0) {
          //  
          // Ignore thumbnail creation if the .notn file has been
          // previously created on an error condition
          //

        } else 
        //
        // Update thumbnail info
        //
        if((highestTn = createTn(pMediaDb, pFileListEntry, bufMedia, bufDb, 
            pFileListEntry->numTn, 1)) > pFileListEntry->numTn || highestTn == -1) {

          pFileListEntry->numTn = highestTn;
          fileListChanged = 1;

          // Periodically update the db file
          if(numTnCreated > 10) {
            file_list_write(pathDb, &fileList);
            numTnCreated = 0;
          }

        }

      }

    } else {
//fprintf(stdout, "skipping %s '%s'\n", pathMedia, direntry->d_name);
    }

  }

  fileops_CloseDir(pdir);

  if(g_proc_exit == 0) {

    if(file_list_removeunmarked(&fileList) || fileListChanged) {

       LOG(X_DEBUG("Writing file index in %s"), pathDb);
//fprintf(stdout, "level:%u\n", level);
      file_list_write(pathDb, &fileList);
    }

    //
    //Remove thumbnails which are not included in the fileList
    //
    clearTn(pathMedia, pathDb, &fileList);
  }

  file_list_close(&fileList);

  return rc;
}
示例#13
0
static int createTn(const MEDIADB_DESCR_T *pMediaDb,
                    FILE_LIST_ENTRY_T *pFileListEntry, 
                    const char *pathMedia, const char *pathTn,
                    int numTn, int maxTnInIter) {
  int rc = 0;
  int highestTn = 0;
  struct stat st;
  unsigned int idx;
  char buf[VSX_MAX_PATH_LEN];
  char cmd[VSX_MAX_PATH_LEN];
  char cmdnice[64];
  char tmpfile[VSX_MAX_PATH_LEN];
  int numTnCreated = 0;
  char avcthumbsize[32];
  unsigned int secOffset;
  const char *avcthumb = pMediaDb->avcthumb;
  const char *avcthumblog = pMediaDb->avcthumblog;
  const char *avcthumb_file = avcthumb;
  const char *avcthumblog2 = avcthumblog;
#ifdef WIN32
  char curdir[VSX_MAX_PATH_LEN];
  char avcthumblogpath[VSX_MAX_PATH_LEN];
  char avcthumblogpath2[VSX_MAX_PATH_LEN];
  char avcthumblogprefix[64];
  size_t sz;
#endif // WIN32
#if defined(FFMPEG_THUMB_NEW)
  const char thumbsizedelim = ':';
#else // (FFMPEG_THUMB_NEW)
  const char thumbsizedelim = 'x';
#endif //  (FFMPEG_THUMB_NEW)

  tmpfile[0] = '\0';
  cmdnice[0] = '\0';

  //fprintf(stdout, "createTn '%s' numTn:%d, maxTnIter:%d, TN_MAX:%d, g_proc_exit:%d (0x%x)\n", pathTn, numTn, maxTnInIter, SRVMEDIA_TN_MAX, g_proc_exit, &g_proc_exit);

  for(idx = 0; idx < SRVMEDIA_TN_MAX; idx++) {

    if(idx > 0) {
      secOffset = (idx - 1) * SRVMEDIA_TN_INTERVAL_SEC;
    } else {
      secOffset = 4;
    }


    if(pFileListEntry->duration == 0) {

      snprintf(tmpfile, sizeof(tmpfile), "%s%s"VSXTMP_EXT, pathTn, pMediaDb->tn_suffix);
      if(fileops_stat(tmpfile, &st) != 0) {
 
        if(numTn == 0 && idx == 0) {
//fprintf(stdout, "creating tmp file '%s'\n", tmpfile);
          //
          // Create tmpfile which should only exist during 
          // creation of thumbnails for source of unknown duration
          // Since the "tn=" parameter in the index file denotes
          // the current number of thumbnails available
          //
          if(fileops_touchfile(tmpfile) != 0) {
            LOG(X_ERROR("Failed to create %s"), tmpfile);
          }
        } else if((int) idx >= numTn) {
//fprintf(stdout, "breaking out, have all the tns %d > %d\n", idx, numTn);
          break;
        }

      } else if(idx == SRVMEDIA_TN_MAX - 1) {
//fprintf(stdout, "removing tmp file '%s'\n", tmpfile);
        fileops_DeleteFile(tmpfile);
      }

    } else if(pFileListEntry->duration > 0 && secOffset >= pFileListEntry->duration - 1) {
      break;
    }

    if(idx == 0) {
      snprintf(avcthumbsize, sizeof(avcthumbsize), "%d%c%d", 
               pMediaDb->smTnWidth, thumbsizedelim, pMediaDb->smTnHeight);
      snprintf(buf, sizeof(buf), "%s%s.jpg", pathTn, pMediaDb->tn_suffix);    
    } else {
      snprintf(avcthumbsize, sizeof(avcthumbsize), "%d%c%d", 
               pMediaDb->lgTnWidth, thumbsizedelim, pMediaDb->lgTnHeight);
      snprintf(buf, sizeof(buf), "%s%s%u.jpg", pathTn, pMediaDb->tn_suffix, idx - 1);    
    }

    if(fileops_stat(buf, &st) < 0  || st.st_size == 0) {

#ifdef WIN32

      //
      // cd into directory of avcthumb script
      //
      avcthumblogprefix[0] = '\0';
      curdir[0] = '\0';
      fileops_getcwd(curdir, sizeof(curdir));
      if((sz = mediadb_getdirlen(avcthumb)) > 0) {
        if(sz >= sizeof(tmpfile)) {
          sz = sizeof(tmpfile) - 1;
        }
        tmpfile[sizeof(tmpfile) - 1] = '\0';
        strncpy(tmpfile, avcthumb, sizeof(tmpfile));
        if(sz > 0) {
          tmpfile[sz] = '\0';
          fileops_setcwd(tmpfile);
          avcthumb_file = &avcthumb[sz];
          snprintf(avcthumblogprefix, sizeof(avcthumblogprefix), "..\\");
        }
      }
      if(avcthumblog) {
        snprintf(avcthumblogpath, sizeof(avcthumblogpath), "%s%s", 
                 avcthumblogprefix, avcthumblog);
        snprintf(avcthumblogpath2, sizeof(avcthumblogpath2), "%s%s.err", 
                 avcthumblogprefix, avcthumblog);
        avcthumblog2 = avcthumblogpath2;
        avcthumblog = avcthumblogpath;
      }

#else

      snprintf(cmdnice, sizeof(cmdnice), "nice -n19 ");

#endif // WIN32
      

#if defined(FFMPEG_THUMB_NEW)
      //
      //TODO: create multiple thumbs on one run... will speed thnigs up alot!
      // '-ss 4 -vf "thumbnail,scale=164:90,fps=1/4" -frames:v 8'
      //
      snprintf(cmd, sizeof(cmd), "%s%s -v warning -i \"%s\" -an -vf \"thumbnail,scale=%s\" "
               "-frames:v 1 -f image2 -vcodec mjpeg -ss %u \"%s\" %s%s %s%s", 
               cmdnice,
               avcthumb_file, pathMedia, avcthumbsize, secOffset, buf, 
               avcthumblog ? ">>" : "", avcthumblog ? avcthumblog : "",
               avcthumblog2 ? "2>>" : "", avcthumblog2 ? avcthumblog2 : "");

#else // (FFMPEG_THUMB_NEW)
      snprintf(cmd, sizeof(cmd), "%s%s -i \"%s\" -an -s \"%s\" "
               "-vframes 1 -f image2 -vcodec mjpeg -ss %u \"%s\" %s%s %s%s", 
               cmdnice,
               avcthumb_file, pathMedia, avcthumbsize, secOffset, buf, 
               avcthumblog ? ">>" : "", avcthumblog ? avcthumblog : "",
               avcthumblog2 ? "2>>" : "", avcthumblog2 ? avcthumblog2 : "");
#endif // (FFMPEG_THUMB_NEW)
    
//if(numcmd++ > 2) {
//  return 0;
//}
      LOG(X_DEBUG("Creating thumbnail '%s'"), cmd);
      //TODO: seems that we're not getting SIGINT in the parent here... need a way to spawn (async?) & wait/poll
      rc = system(cmd);

#ifdef WIN32
      if(curdir[0] != '\0') {
        fileops_setcwd(curdir);
      }
#endif // WIN3

      //LOG(X_DEBUG("DOING STAT ON '%s'"), buf);
      if(fileops_stat(buf, &st) == 0  && st.st_size > 0) {
        rc = 0;
        highestTn = idx + 1;
        if(maxTnInIter > 0 && ++numTnCreated >= maxTnInIter) {
          break;
        }
      } else {
        rc = -1;
        LOG(X_WARNING("Failed to generate thumbnail '%s'"), buf);

        if(pFileListEntry->duration == 0) {
          snprintf(tmpfile, sizeof(tmpfile), "%s%s"VSXTMP_EXT, pathTn, pMediaDb->tn_suffix);    

          if(fileops_stat(tmpfile, &st) == 0) {
            fileops_DeleteFile(tmpfile);
          }
        } else {
          snprintf(tmpfile, sizeof(tmpfile), "%s%s."NOTN_EXT, pathTn, pMediaDb->tn_suffix);    
          if(fileops_touchfile(tmpfile) != 0) {
            LOG(X_ERROR("Failed to create %s"), tmpfile);
          }
        }

        if(idx == 0) {
          return -1;
        }
        break;
      }

    } else {
      highestTn = idx + 1;
    }

  }
  
  return highestTn;
}
示例#14
0
static int update_fileentry(FILE_LIST_T *pFileList, const char *mediaName, 
                            const char *mediaPath, FILE_LIST_ENTRY_T **ppEntry) {
  MEDIA_DESCRIPTION_T mediaDescr;
  FILE_STREAM_T fileStream;
  FILE_LIST_ENTRY_T *pFileEntryCur = NULL;
  FILE_LIST_ENTRY_T *pFileEntryNew = NULL;
  FILE_LIST_ENTRY_T fileEntry;
  char buf[VSX_MAX_PATH_LEN];
  struct stat st;
  struct stat st2;
  int havestat = 0;
  size_t szt;
  int fileChanged = 1;

  memset(&fileEntry, 0, sizeof(fileEntry));
      
//fprintf(stdout, "looking for '%s'\n", mediaName);
  if((pFileEntryCur = file_list_find(pFileList, mediaName))) {

    //fprintf(stdout, "found entry '%s' numTn:%d\n", pFileEntryCur->name, pFileEntryCur->numTn);

    // mark the entry as current to avoid deletion
    pFileEntryCur->flag = 1;
        
    if((havestat = !fileops_stat(mediaPath, &st)) == 0) {
      LOG(X_ERROR("Unable to stat '%s'"), mediaPath);
    } else if(st.st_size == pFileEntryCur->size &&
              st.st_ctime == pFileEntryCur->tm) {

      fileChanged = 0;

      //
      // Special case to probe for recent creation .seek file
      // since the last time this entry was written
      //
      if(pFileEntryCur->duration == 0) {
        buf[sizeof(buf) - 1] = '\0';
        strncpy(buf, mediaPath, sizeof(buf) - 1);
        if((szt = strlen(buf))) {
          strncpy(&buf[szt], MP2TS_FILE_SEEKIDX_NAME, sizeof(buf) - szt - 1);
        }
        if(fileops_stat(buf, &st2) == 0) {
          fileChanged = 1;        
        }
      }

    }
    pFileEntryNew = pFileEntryCur;

  } else {

    // Check for invalid chars - ',' is used as a delimeter in .avcfidx
    if(strchr(mediaName, ',') || mediaName[0] == '#' || mediaName[0] == ' ' ||
              mediaName[0] == '=') {
      LOG(X_WARNING("Illegal filename '%s' not added to database"), mediaPath);
      pFileEntryNew = NULL;
      fileChanged = 0;
    } else {
      LOG(X_DEBUG("Could not find database entry '%s'"), mediaPath);
      pFileEntryNew = &fileEntry;
    }
  }

  if(fileChanged) {

    if(OpenMediaReadOnly(&fileStream, mediaPath) == 0) {

      memset(&mediaDescr, 0, sizeof(mediaDescr));

      if(filetype_getdescr(&fileStream, &mediaDescr, 1) == 0) {

         pFileEntryNew->flag = 1;
         pFileEntryNew->duration = mediaDescr.durationSec; 
         pFileEntryNew->size = mediaDescr.totSz;

         if(!havestat && (havestat = !fileops_stat(mediaPath, &st)) == 0) {
           LOG(X_ERROR("Unable to stat new entry '%s'"), mediaPath);
         }
         if(havestat) {
           pFileEntryNew->tm = st.st_ctime;
//fprintf(stderr, "-----------set tm:%ld %s\n", pFileEntryNew->tm, mediaPath);
         }

         if(mediaDescr.haveVid) {
           create_viddescrstr(&mediaDescr, pFileEntryNew->vstr, sizeof(pFileEntryNew->vstr));
         }
         if(mediaDescr.haveAud) {
           create_auddescrstr(&mediaDescr, pFileEntryNew->astr, sizeof(pFileEntryNew->astr));
           //fprintf(stdout, "aud descr:'%s'\n", pFileEntryNew->astr);
         }

       } else {
         pFileEntryNew->flag = 1;
         pFileEntryNew->size = fileStream.size;
       }

       CloseMediaFile(&fileStream);
    } // end of OpenMediaReadOnly

    if(pFileEntryCur == NULL) {
      pFileEntryNew->name[sizeof(pFileEntryNew->name) - 1] = '\0';
      strncpy(pFileEntryNew->name, mediaName, sizeof(pFileEntryNew->name) - 1);
      pFileEntryCur = file_list_addcopy(pFileList, pFileEntryNew);
    }
  } // end of if(fileChanged)

  if(ppEntry) {
    *ppEntry = pFileEntryCur;
  }

  return fileChanged; 
}
示例#15
0
DIR_ENTRY_LIST_T *direntry_getentries(const MEDIADB_DESCR_T *pMediaDb, 
                                      const char *dir, 
                                      const char *fidxdir, 
                                      const char *searchstr,
                                      int includedirs,
                                      unsigned int startidx,
                                      unsigned int max,
                                      enum DIR_SORT sort) {
  DIR *pdir;
  int rc = 0;
  struct dirent *direntry;
  char path[VSX_MAX_PATH_LEN];
  struct stat st;
  int addEntry;
  FILE_LIST_T fileList;
  FILE_LIST_ENTRY_T *pFileEntry = NULL;
  META_FILE_T metaFile;
  DIR_ENTRY_LIST_T *pEntryList = NULL;
  DIR_ENTRY_T entry;
  DIR_ENTRY_T *pEntry;
  const char *pdispname;
  unsigned int idx = 0;
  unsigned int cnt = 0;
  unsigned int cntInDir = 0;
  COMPARE_DIR_ENTRY compareFunc = direntry_getcompfunc(sort);

  VSX_DEBUG_MGR( LOG(X_DEBUG("MGR - direntry_getentries dir: '%s', fidxdir: '%s', searchstr: '%s', "
                             "includedirs: %d, startidx: %d, max: %d"), 
                            dir, fidxdir, searchstr, includedirs, startidx, max));

  if(!(pdir = fileops_OpenDir(dir))) {
    return NULL;
  }

  memset(&fileList, 0, sizeof(fileList));
  if(fidxdir) { 
    file_list_read(fidxdir, &fileList);
  }

  //
  // Read the directory wide metafile to get a list of 'ignore' entries
  //
  memset(&metaFile, 0, sizeof(metaFile));
  mediadb_prepend_dir(dir, METAFILE_DEFAULT, path, sizeof(path));
  if(fileops_stat(path, &st) == 0) {
    metafile_open(path, &metaFile, 1, 1);
  }

  while((direntry = fileops_ReadDir(pdir))) {

    VSX_DEBUG_MGR( LOG(X_DEBUGV("MGR - direntry_getentries d_name: '%s', isdir: %d"), 
           direntry->d_name, (direntry->d_type & DT_DIR)) );

    if(is_entry_ignored(metaFile.pignoreList, direntry->d_name)) {
      continue;
    }

    if(!(pdispname = find_entry_description(metaFile.pDescriptionList,
                                     direntry->d_name))) {
      pdispname = direntry->d_name;
    }

    if(searchstr && !is_match_search(pdispname, NULL, searchstr)) {
      continue;
    }

    memset(&entry, 0, sizeof(entry));
    strncpy(entry.d_name, direntry->d_name, sizeof(entry.d_name) - 1); 
    if(pdispname != direntry->d_name) {
      strncpy(entry.displayname, pdispname, sizeof(entry.displayname) - 1); 
    }
    entry.d_type = direntry->d_type;
    addEntry = 0;

    if(direntry->d_type & DT_DIR) {

      if(includedirs && mediadb_isvalidDirName(pMediaDb, direntry->d_name)) {
        addEntry = 1;
      }

    } else if(mediadb_isvalidFileName(pMediaDb, direntry->d_name, 1, 1)) {

      mediadb_prepend_dir(dir, direntry->d_name, path, sizeof(path));
      if(fileops_stat(path, &st) == 0) {
        entry.size = st.st_size;
        //entry.tm = st.st_mtime;
        entry.tm = st.st_ctime;

        if(fidxdir && (pFileEntry = file_list_find(&fileList, direntry->d_name))) {
          entry.numTn = pFileEntry->numTn; 
          entry.duration = pFileEntry->duration;
        }
        addEntry = 1;
      }

    }

    if(addEntry) {
      VSX_DEBUG_MGR( LOG(X_DEBUGV("MGR - direntry_getentries add d_name: '%s', isdir: %d"), 
           direntry->d_name, (direntry->d_type & DT_DIR)) );

      if(compareFunc || (idx >= startidx && (max == 0 || cnt < max))) {

        if(cnt >= DIR_ENTRY_LIST_BUFNUM) {
          LOG(X_WARNING("Not showing more than %d entries in %s"), cnt, dir);
          break;
        } else if(!(pEntry = direntry_addsorted(&pEntryList, &entry, compareFunc))) {
          LOG(X_ERROR("Failed to add directory entry '%s' to list"), direntry->d_name);
          rc = -1;
          break;
        }
        cnt++;
      }

      idx++;
      cntInDir++;
    }

  }

  //
  // Since when a sort is requested we have to sort every entry in the directory.  Now we can move the head pointer
  // to the first desired entry
  //
  if(pEntryList && compareFunc && startidx > 0) {
    pEntry = pEntryList->pHead;
    for(idx = 0; idx < startidx; idx++) {
      pEntry = pEntry->pnext;
      cnt--;
    }
    pEntryList->pHead = pEntry;
    if(cnt > max) {
      cnt = max;
    }
    //fprintf(stderr, "moved phead to %s, cnt:%d, cntInDir:%d\n", pEntryList->pHead ? pEntryList->pHead->d_name : NULL, cnt, cntInDir);
  }
  

  fileops_CloseDir(pdir);
  if(fidxdir) {
    file_list_close(&fileList);
  }
  metafile_close(&metaFile);

  if(rc == 0 && !pEntryList) {
    // If the user requested an index out of bounds, return an empty list with
    // a valid cntTotalInDir
    pEntryList = (DIR_ENTRY_LIST_T *) avc_calloc(1, sizeof(DIR_ENTRY_LIST_T));
  }

  if(pEntryList) {
    pEntryList->cntTotal = cnt; 
    pEntryList->cntTotalInDir = cntInDir; 
  }

  //if(pEntryList) fprintf(stderr, "DIR '%s' num:%d numAlloc:%d pnext:0x%x TOTAL:%d/%d\n", dir, pEntryList->num, pEntryList->numAlloc, pEntryList->pnext, pEntryList->cntTotal, pEntryList->cntTotalInDir);
 
  return pEntryList;
}