Skip to content

Commit 1ce6d08

Browse files
Support of more file formats, including the ones with no frame count or no duration
1 parent 4bb2988 commit 1ce6d08

File tree

5 files changed

+65
-30
lines changed

5 files changed

+65
-30
lines changed

Source/Core/FFmpeg_Glue.cpp

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ FFmpeg_Glue::FFmpeg_Glue (const string &FileName_, int Scale_Width_, int Scale_H
103103
VideoFrameCount=0;
104104
VideoFrameCount_Max=0;
105105
VideoDuration=0;
106+
VideoFirstTimeStamp=(uint64_t)-1;
106107
IsComplete=false;
107108

108109
// FFmpeg pointers
@@ -180,7 +181,20 @@ FFmpeg_Glue::FFmpeg_Glue (const string &FileName_, int Scale_Width_, int Scale_H
180181
if (VideoStream)
181182
{
182183
VideoFrameCount_Max=VideoFrameCount=VideoStream->nb_frames;
183-
VideoDuration=((double)VideoStream->duration)*VideoStream->time_base.num/VideoStream->time_base.den;
184+
if (VideoStream->duration!=AV_NOPTS_VALUE)
185+
VideoDuration=((double)VideoStream->duration)*VideoStream->time_base.num/VideoStream->time_base.den;
186+
187+
// If video duration is not known, estimating it
188+
if (VideoDuration==0 && FormatContext->duration!=AV_NOPTS_VALUE)
189+
VideoDuration=((double)FormatContext->duration)/AV_TIME_BASE;
190+
191+
// If frame count is not known, estimating it
192+
if (VideoFrameCount==0 && VideoStream->avg_frame_rate.num && VideoStream->avg_frame_rate.den && VideoDuration)
193+
VideoFrameCount=VideoDuration*VideoStream->avg_frame_rate.num/VideoStream->avg_frame_rate.den;
194+
if (VideoFrameCount==0
195+
&& ((VideoStream->time_base.num==1 && VideoStream->time_base.den>=24 && VideoStream->time_base.den<=60)
196+
|| (VideoStream->time_base.num==1001 && VideoStream->time_base.den>=24000 && VideoStream->time_base.den<=60000)))
197+
VideoFrameCount=VideoStream->duration;
184198
}
185199
if (VideoFrameCount_Max==0)
186200
{
@@ -319,9 +333,9 @@ FFmpeg_Glue::FFmpeg_Glue (const string &FileName_, int Scale_Width_, int Scale_H
319333
key_frame[x_Max]=1; //Forcing key_frame to 1 if it is missing from the XML, for decoding
320334

321335
x_Max++;
322-
if (VideoFrameCount<x_Max)
336+
if (x_Max>=VideoFrameCount)
323337
{
324-
VideoFrameCount=x_Max;
338+
VideoFrameCount=x_Max+1;
325339
if (!ts.empty() && ts!="N/A")
326340
VideoDuration=x[1][x_Max-1]+d[x_Max-1];
327341
if (FormatContext==NULL)
@@ -437,7 +451,7 @@ void FFmpeg_Glue::Seek(size_t Pos)
437451
// DTS computing
438452
long long DTS=Pos;
439453
DTS*=VideoStream->duration;
440-
DTS/=VideoFrameCount;
454+
DTS/=VideoFrameCount; // TODO: seek based on time stamp
441455
DTS_Target=(int)DTS;
442456

443457
// Seek
@@ -595,6 +609,8 @@ bool FFmpeg_Glue::OutputFrame(AVPacket* TempPacket, bool Decode)
595609
Image2=NULL;
596610
Jpeg.Data=NULL;
597611
Jpeg.Size=0;
612+
TempPacket->data+=TempPacket->size;
613+
TempPacket->size=0;
598614
return true;
599615
}
600616
TempPacket->data+=Bytes;
@@ -863,10 +879,27 @@ bool FFmpeg_Glue::Process(AVFrame* &FilteredFrame, AVFilterGraph* &FilterGraph,
863879
if (WithStats)
864880
{
865881
x[0][x_Max]=x_Max;
866-
int64_t ts=(Frame->pkt_pts==AV_NOPTS_VALUE)?Frame->pkt_dts:Frame->pkt_pts; // Using DTS is PTS is not available
882+
int64_t ts=Frame->pkt_dts;
883+
if (ts==AV_NOPTS_VALUE && x_Max)
884+
ts=(int)((x[1][x_Max-1]*x_Max/(x_Max-1))/VideoStream->time_base.num*VideoStream->time_base.den)+VideoFirstTimeStamp; //TODO: understand how to do with first timestamp not being 0 and last timestamp being AV_NOPTS_VALUE e.g. op1a-mpeg2-wave_hd.mxf
885+
//int64_t ts=(Frame->pkt_pts==AV_NOPTS_VALUE)?Frame->pkt_dts:Frame->pkt_pts; // Using DTS is PTS is not available // TODO: check if stats are based on DTS or PTS
886+
if (VideoFirstTimeStamp==(uint64_t)-1)
887+
VideoFirstTimeStamp=ts;
888+
if (ts<VideoFirstTimeStamp)
889+
{
890+
for (size_t Pos=0; Pos<x_Max; Pos++)
891+
{
892+
x[1][Pos]-=VideoFirstTimeStamp-ts;
893+
x[2][Pos]=x[1][Pos]/60;
894+
x[3][Pos]=x[2][Pos]/60;
895+
}
896+
}
897+
ts-=VideoFirstTimeStamp;
867898
if (ts!=AV_NOPTS_VALUE)
868899
{
869900
x[1][x_Max]=((double)ts)*VideoStream->time_base.num/VideoStream->time_base.den;
901+
if (x[1][x_Max]>VideoDuration)
902+
VideoDuration=x[1][x_Max];
870903
x[2][x_Max]=x[1][x_Max]/60;
871904
x[3][x_Max]=x[2][x_Max]/60;
872905
}
@@ -931,6 +964,8 @@ bool FFmpeg_Glue::Process(AVFrame* &FilteredFrame, AVFilterGraph* &FilterGraph,
931964
key_frame[x_Max]=Frame->key_frame;
932965

933966
x_Max++;
967+
if (x_Max>=VideoFrameCount)
968+
VideoFrameCount=x_Max+1;
934969
}
935970

936971
if (GetAnswer==AVERROR(EAGAIN) || GetAnswer==AVERROR_EOF)

Source/Core/FFmpeg_Glue.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,11 @@ class FFmpeg_Glue
161161
bool With2;
162162

163163
// Status information
164-
size_t VideoFramePos; // Current pos
164+
size_t VideoFramePos; // Current position of playback
165165
size_t VideoFrameCount; // Total count of frames (may be estimated)
166166
size_t VideoFrameCount_Max; // Max reserved memory
167167
double VideoDuration; // Duration is seconds
168+
uint64_t VideoFirstTimeStamp; // Timestamp of the first frame
168169

169170
// Temp
170171
int DTS_Target;

Source/GUI/Plots.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ Plots::Plots(QWidget *parent, FileInformation* FileInformationData_) :
7171

7272
// Y axis info
7373
memset(plots_YMax, 0, sizeof(double)*PlotType_Max);
74+
VideoFrameCount=0;
7475

7576
// Plots
7677
Plots_Create();
@@ -367,6 +368,13 @@ void Plots::createData_Update()
367368
for (size_t Type=0; Type<PlotType_Max; Type++)
368369
if (plots[Type] && plots[Type]->isVisible())
369370
createData_Update((PlotType)Type);
371+
372+
//Update of zoom in case of total duration change
373+
if (VideoFrameCount!=FileInfoData->Glue->VideoFrameCount_Get())
374+
{
375+
VideoFrameCount=FileInfoData->Glue->VideoFrameCount_Get();
376+
Zoom_Update();
377+
}
370378
}
371379

372380
//---------------------------------------------------------------------------
@@ -433,6 +441,18 @@ void Plots::createData_Update(PlotType Type)
433441
plots[Type]->replot();
434442
}
435443

444+
//---------------------------------------------------------------------------
445+
void Plots::Zoom_Update()
446+
{
447+
size_t Increment=FileInfoData->Glue->VideoFrameCount_Get()/ZoomScale;
448+
int Pos=FileInfoData->Frames_Pos_Get();
449+
if (Pos>Increment/2)
450+
Pos-=Increment/2;
451+
else
452+
Pos=0;
453+
Zoom_Move(Pos);
454+
}
455+
436456
//---------------------------------------------------------------------------
437457
void Plots::Zoom_Move(size_t Begin)
438458
{
@@ -671,11 +691,5 @@ void Plots::on_XAxis_Kind_currentIndexChanged(int index)
671691
plots[Type]->replot();
672692
}
673693

674-
size_t Increment=FileInfoData->Glue->VideoFrameCount_Get()/ZoomScale;
675-
int Pos=FileInfoData->Frames_Pos_Get();
676-
if (Pos>Increment/2)
677-
Pos-=Increment/2;
678-
else
679-
Pos=0;
680-
Zoom_Move(Pos);
694+
Zoom_Update();
681695
}

Source/GUI/Plots.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class Plots : public QWidget
7878
void refreshDisplay_Axis ();
7979

8080
// Zoom
81+
void Zoom_Update ();
8182
void Zoom_Move (size_t Begin);
8283
void Zoom_In ();
8384
void Zoom_Out ();
@@ -103,6 +104,7 @@ class Plots : public QWidget
103104

104105
// Y axis info
105106
double plots_YMax[PlotType_Max];
107+
uint64_t VideoFrameCount;
106108

107109
private Q_SLOTS:
108110
void plot_moved( const QPointF & );

Source/GUI/mainwindow_More.cpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,6 @@ void MainWindow::processFile(const QString &FileName)
127127
Files_CurrentPos=0;
128128
ui->fileNamesBox->addItem(FileName);
129129

130-
// Coherency
131-
if (Files[Files_CurrentPos]->Glue->VideoFrameCount_Get()==0)
132-
{
133-
statusBar()->showMessage("Unsupported format", 10000);
134-
return;
135-
}
136-
137130
TimeOut();
138131
}
139132

@@ -318,16 +311,6 @@ void MainWindow::addFile(const QString &FileName)
318311
// Launch analysis
319312
FileInformation* Temp=new FileInformation(this, FileName);
320313

321-
// Coherency
322-
if (Temp->Glue->VideoFrameCount_Get()==0)
323-
{
324-
delete Temp;
325-
QMessageBox msgBox;
326-
msgBox.setText("The file format of "+FileName+" is not yet supported.");
327-
msgBox.exec();
328-
return;
329-
}
330-
331314
Files.push_back(Temp);
332315
ui->fileNamesBox->addItem(Temp->FileName);
333316

0 commit comments

Comments
 (0)