Added FLV::seekToTagType function for fast FLV seeking, now used in MistInFLV

This commit is contained in:
Thulinma 2017-03-02 17:26:39 +01:00
parent bea605fd18
commit 0ea100758d
3 changed files with 50 additions and 0 deletions

View file

@ -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 <stdio.h> //for Tag::FileLoader
#include <unistd.h> //for Tag::FileLoader
#include <fcntl.h> //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.

View file

@ -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:

View file

@ -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())){