Add a simple video decoding test

This application tests the BMediaTrack/BMediaFile API and underlying
ffmpeg plugin for video decoding. You can press (or hold) any key to go
through frames in a video. This avoids debugging both MediaPlayer and
the underlying libraries at the same time.

It shows that ReadFrames is getting video frames out of PTS order.
This commit is contained in:
Adrien Destugues 2017-12-07 22:40:48 +01:00
parent a9020afcb6
commit 2d10453741
2 changed files with 135 additions and 0 deletions

View File

@ -7,6 +7,10 @@ SimpleTest mediaFormats :
mediaFormats.cpp
: media ;
SimpleTest VideoDecoder :
VideoDecoder.cpp
: media be ;
UnitTestLib libmediatest.so :
MediaKitTestAddon.cpp

View File

@ -0,0 +1,131 @@
/*
* Copyright 2017, Adrien Destugues, pulkomandy@pulkomandy.tk
* Distributed under terms of the MIT license.
*/
#include <Application.h>
#include <Bitmap.h>
#include <File.h>
#include <MediaFile.h>
#include <MediaTrack.h>
#include <Window.h>
#include <stdio.h>
#pragma mark - VideoView
class VideoView: public BView
{
public:
VideoView::VideoView(BMediaTrack* track, int32 width, int32 height);
void Draw(BRect);
void KeyDown(const char*, int32);
private:
BMediaTrack* fMediaTrack;
BBitmap fBitmap;
};
VideoView::VideoView(BMediaTrack* track, int32 width, int32 height)
: BView(BRect(0, 0, width, height), "Video", B_FOLLOW_NONE,
B_WILL_DRAW)
, fMediaTrack(track)
, fBitmap(BRect(0, 0, width - 1, height - 1), B_RGB32)
{
}
void
VideoView::Draw(BRect r)
{
DrawBitmap(&fBitmap);
}
void
VideoView::KeyDown(const char*, int32)
{
puts("Next frame");
int64 count = 1;
fMediaTrack->ReadFrames(fBitmap.Bits(), &count);
Invalidate();
}
#pragma mark - VideoWindow
class VideoWindow: public BWindow
{
public:
VideoWindow::VideoWindow(const char* videoFile);
VideoWindow::~VideoWindow();
private:
BFile* fFile;
BMediaFile* fMediaFile;
BMediaTrack* fMediaTrack;
};
VideoWindow::VideoWindow(const char* path)
: BWindow(BRect(60, 120, 700, 600), "Video Decoder",
B_DOCUMENT_WINDOW, B_QUIT_ON_WINDOW_CLOSE)
, fMediaTrack(NULL)
{
fFile = new BFile(path, B_READ_ONLY);
fMediaFile = new BMediaFile(fFile);
media_format format;
int i;
for (i = fMediaFile->CountTracks(); --i >= 0;) {
BMediaTrack* mediaTrack = fMediaFile->TrackAt(i);
mediaTrack->EncodedFormat(&format);
if (format.IsVideo()) {
fMediaTrack = mediaTrack;
fMediaTrack->DecodedFormat(&format);
break;
}
}
if (fMediaTrack) {
printf("Found video track\n%ld x %ld ; %lld frames, %f seconds\n",
format.Width(), format.Height(), fMediaTrack->CountFrames(),
fMediaTrack->Duration() / 1000000.f);
} else {
return;
}
BView* view = new VideoView(fMediaTrack, format.Width(), format.Height());
AddChild(view);
view->MakeFocus();
}
VideoWindow::~VideoWindow()
{
delete fMediaFile; // Also deletes the track
delete fFile;
}
#pragma mark - Main
int main(int argc, char* argv[])
{
if (argc < 2)
return -1;
BApplication app("application/x-vnd.Haiku-VideoDecoder");
BWindow* window = new VideoWindow(argv[1]);
window->Show();
app.Run();
}