From 0ea100758d303fefae795624922b34e3f5d239ab Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 2 Mar 2017 17:26:39 +0100 Subject: [PATCH] Added FLV::seekToTagType function for fast FLV seeking, now used in MistInFLV --- lib/flv_tag.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ lib/flv_tag.h | 3 +++ src/input/input_flv.cpp | 6 ++++++ 3 files changed, 50 insertions(+) diff --git a/lib/flv_tag.cpp b/lib/flv_tag.cpp index 70636616..e6683c35 100644 --- a/lib/flv_tag.cpp +++ b/lib/flv_tag.cpp @@ -1,9 +1,11 @@ /// \file flv_tag.cpp /// Holds all code for the FLV namespace. +#include "defines.h" #include "rtmpchunks.h" #include "flv_tag.h" #include "timing.h" +#include "util.h" #include //for Tag::FileLoader #include //for Tag::FileLoader #include //for Tag::FileLoader @@ -52,6 +54,45 @@ bool FLV::is_header(char * header) { return true; } //FLV::is_header + +/// Helper function that can quickly skip through a file looking for a particular tag type +bool FLV::seekToTagType(FILE * f, uint8_t t){ + long long startPos = Util::ftell(f); + DONTEVEN_MSG("Starting seek at %lld", startPos); + char buf[4]; + if (fread(buf, 4, 1, f) != 1){return false;} + while (!feof(f) && !ferror(f)){ + switch (buf[0]){ + case 0x09: + case 0x08: + case 0x12: + { + if (t == buf[0]){ + if (fseek(f, -4, SEEK_CUR)){ + WARN_MSG("Could not seek back in FLV stream!"); + } + INSANE_MSG("Found tag of type %u at %lld", t, Util::ftell(f)); + return true; + } + long len = (buf[1] << 16) | (buf[2] << 8) | buf[3]; + if (fseek(f, len+11, SEEK_CUR)){ + WARN_MSG("Could not seek forward in FLV stream!"); + }else{ + DONTEVEN_MSG("Seeking %ld+4 bytes forward, now at %lld", len+11, Util::ftell(f)); + } + if (fread(buf, 4, 1, f) != 1){return false;} + } + break; + default: + WARN_MSG("Invalid FLV tag detected! Aborting search."); + if (fseek(f, -4, SEEK_CUR)){ + WARN_MSG("Could not seek back in FLV stream!"); + } + return false; + } + } +} + /// True if this media type requires init data. /// Will always return false if the tag type is not 0x08 or 0x09. /// Returns true for H263, AVC (H264), AAC. diff --git a/lib/flv_tag.h b/lib/flv_tag.h index 4e430830..0dbc6fd3 100644 --- a/lib/flv_tag.h +++ b/lib/flv_tag.h @@ -24,6 +24,9 @@ namespace FLV { bool check_header(char * header); ///< Checks a FLV Header for validness. bool is_header(char * header); ///< Checks the first 3 bytes for the string "FLV". + /// Helper function that can quickly skip through a file looking for a particular tag type + bool seekToTagType(FILE * f, uint8_t type); + /// This class is used to hold, work with and get information about a single FLV tag. class Tag { public: diff --git a/src/input/input_flv.cpp b/src/input/input_flv.cpp index 9d8f6557..66ffa930 100644 --- a/src/input/input_flv.cpp +++ b/src/input/input_flv.cpp @@ -103,6 +103,12 @@ namespace Mist { void inputFLV::getNext(bool smart) { long long int lastBytePos = Util::ftell(inFile); + if (selectedTracks.size() == 1){ + uint8_t targetTag = 0x08; + if (selectedTracks.count(1)){targetTag = 0x09;} + if (selectedTracks.count(3)){targetTag = 0x12;} + FLV::seekToTagType(inFile, targetTag); + } while (!feof(inFile) && !FLV::Parse_Error){ if (tmpTag.FileLoader(inFile)){ if ( !selectedTracks.count(tmpTag.getTrackID())){