in tmk/cpp/hashing/filehasher.cpp [28:129]
bool hashVideo(
int downsampleFrameDimension,
std::string ffmpegGeneratorCommand,
io::TMKFramewiseAlgorithm tmkFramewiseAlgorithm,
int resampleFramesPerSecond,
facebook::tmk::algo::TMKFeatureVectors& tmkFeatureVectors,
bool verbose,
const char* argv0) {
if (verbose) {
fprintf(stderr, "%s\n", ffmpegGeneratorCommand.c_str());
}
FILE* inputFp = popen(ffmpegGeneratorCommand.c_str(), POPEN_MODE);
if (inputFp == nullptr) {
fprintf(stderr, "%s: ffmpeg to generate video stream failed\n", argv0);
return false;
}
// ----------------------------------------------------------------
std::unique_ptr<tmk::hashing::AbstractFrameBufferHasher> phasher =
tmk::hashing::FrameBufferHasherFactory::createFrameHasher(
tmkFramewiseAlgorithm,
downsampleFrameDimension,
downsampleFrameDimension);
if (phasher == nullptr) {
fprintf(stderr, "Error: Phasher is null");
return false;
}
int frameFeatureDimension = phasher->getFeatureDimension();
// ----------------------------------------------------------------
// Allocate this and re-use it over frames, rather than allocating/freeing
// on each frame.
std::unique_ptr<uint8_t[]> rawFrameBuffer(
new uint8_t[downsampleFrameDimension * downsampleFrameDimension * 3]);
std::vector<float> feature(frameFeatureDimension);
std::vector<int> periods =
facebook::tmk::algo::TMKFeatureVectors::makePoullotPeriods();
std::vector<float> fourierCoefficients =
facebook::tmk::algo::TMKFeatureVectors::makePoullotFourierCoefficients();
tmkFeatureVectors = facebook::tmk::algo::TMKFeatureVectors(
tmkFramewiseAlgorithm,
resampleFramesPerSecond,
periods,
fourierCoefficients,
frameFeatureDimension);
try {
bool eof = false;
while (!feof(inputFp)) {
bool read_rc = facebook::tmk::io::readRGBTriples(
rawFrameBuffer.get(),
downsampleFrameDimension,
downsampleFrameDimension,
inputFp,
eof);
if (eof) {
break;
}
if (!read_rc) {
perror("fread");
fprintf(
stderr,
"%s: failed to read frame buffer %d.\n",
argv0,
tmkFeatureVectors.getFrameFeatureCount());
return false;
}
if (!phasher->hashFrame(rawFrameBuffer.get(), feature)) {
fprintf(
stderr,
"%s: failed to hash frame buffer %d.\n",
argv0,
tmkFeatureVectors.getFrameFeatureCount());
return false;
}
tmkFeatureVectors.ingestFrameFeature(
feature, tmkFeatureVectors.getFrameFeatureCount());
}
} catch (const exception& e) {
fprintf(stderr, "%s: failed to download and hash video.\n", argv0);
fprintf(stderr, "%s\n", e.what());
return false;
}
tmkFeatureVectors.finishFrameFeatureIngest();
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// This includes failure to exec the subordinate process.
int pclose_rc = pclose(inputFp);
if (pclose_rc != 0) {
fprintf(stderr, "%s: ffmpeg pclose return code %d.\n", argv0, pclose_rc);
return false;
}
return true;
}