You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
228 lines
6.4 KiB
228 lines
6.4 KiB
9 years ago
|
//------------------------------------------------------------------------------
|
||
|
//
|
||
|
// Project: Anonymizer
|
||
|
//
|
||
|
// Brno University of Technology
|
||
|
// Faculty of Information Technology
|
||
|
//
|
||
|
//------------------------------------------------------------------------------
|
||
|
//
|
||
|
// This project was financially supported by project VG20102015006 funds
|
||
|
// provided by Ministry of the Interior of the Czech republic.
|
||
|
//
|
||
|
//------------------------------------------------------------------------------
|
||
|
/*!
|
||
|
|
||
|
@file ffmpegplayer.h
|
||
|
@brief Header file
|
||
|
@details Details
|
||
|
@authors Martin Borek (mborekcz@gmail.com)
|
||
|
@authors Filip Orsag (orsag@fit.vutbr.cz)
|
||
|
@date 2014-2015
|
||
|
@note This project was supported by MV CR project VG20102015006.
|
||
|
@copyright BUT OPEN SOURCE LICENCE (see License.txt)
|
||
|
|
||
|
*/
|
||
|
|
||
|
#ifndef FFMPEGPLAYER_H
|
||
|
#define FFMPEGPLAYER_H
|
||
|
|
||
|
#include <set>
|
||
|
#include <string> // For video path (videoAddr)
|
||
|
#include "videoframe.h"
|
||
|
|
||
|
#include <QApplication>
|
||
|
#include <QProgressDialog>
|
||
|
|
||
|
//TODO: Are they needed in the header file or can they be moved to the source?
|
||
|
#include <opencv/cv.h>
|
||
|
#include <opencv/cvaux.h>
|
||
|
#include <opencv/cxcore.h>
|
||
|
#include <opencv/highgui.h>
|
||
|
|
||
|
extern "C"{
|
||
|
#include <libavcodec/avcodec.h>
|
||
|
#include <libavformat/avformat.h>
|
||
|
#include <libswscale/swscale.h>
|
||
|
|
||
|
#include <libavutil/common.h>
|
||
|
#include <libavutil/imgutils.h>
|
||
|
#include <libavutil/mathematics.h>
|
||
|
#include <libavutil/samplefmt.h>
|
||
|
|
||
|
#include <libavutil/avassert.h>
|
||
|
#include <libavutil/channel_layout.h>
|
||
|
#include <libavutil/opt.h>
|
||
|
#include <libavutil/timestamp.h>
|
||
|
#include <libswresample/swresample.h>
|
||
|
}
|
||
|
|
||
|
struct OpenException : public std::exception{};
|
||
|
struct UserCanceledOpeningException : public std::exception{};
|
||
|
|
||
|
class FFmpegPlayer
|
||
|
{
|
||
|
public:
|
||
|
/**
|
||
|
* Constructor
|
||
|
* @param videoAddr Path to a video file
|
||
|
* @param progressDialog QT progress dialog for displaying information about video opening
|
||
|
*/
|
||
|
FFmpegPlayer(std::string videoAddr, QProgressDialog const *progressDialog);
|
||
|
|
||
|
/**
|
||
|
* Destructor
|
||
|
*/
|
||
|
~FFmpegPlayer();
|
||
|
|
||
|
/**
|
||
|
* Returns information about frames per second.
|
||
|
* @return Frames per second
|
||
|
*/
|
||
|
double get_fps() const;
|
||
|
|
||
|
/**
|
||
|
* Returns information about number of frames.
|
||
|
* @return Number of frames
|
||
|
*/
|
||
|
unsigned long get_frame_count() const;
|
||
|
|
||
|
/**
|
||
|
* Returns information about video length.
|
||
|
* @return Video length in milliseconds
|
||
|
*/
|
||
|
unsigned long get_total_time() const;
|
||
|
|
||
|
/**
|
||
|
* Returns information about video height.
|
||
|
* @return Video height
|
||
|
*/
|
||
|
unsigned int get_height() const;
|
||
|
|
||
|
/**
|
||
|
* Returns information about video width.
|
||
|
* @return Video width
|
||
|
*/
|
||
|
unsigned int get_width() const;
|
||
|
|
||
|
//int64_t get_frame_timestamp() const;
|
||
|
//int get_time_position() const; // In milliseconds
|
||
|
|
||
|
/**
|
||
|
* Returns information about the input video stream.
|
||
|
* @return Input video stream
|
||
|
*/
|
||
|
AVStream const *get_video_stream();
|
||
|
|
||
|
/**
|
||
|
* Returns information about the input audio stream.
|
||
|
* @return Input audio stream
|
||
|
*/
|
||
|
AVStream const *get_audio_stream();
|
||
|
|
||
|
/**
|
||
|
* Reads a frame by its time position and returns it.
|
||
|
* @param resultFrame Read frame
|
||
|
* @param time Time position
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool get_frame_by_time(VideoFrame *resultFrame, unsigned long time);
|
||
|
|
||
|
/**
|
||
|
* Reads a frame by its timestamp and returns it.
|
||
|
* @param resultFrame Read frame
|
||
|
* @param timestamp Timestamp
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool get_frame_by_timestamp(VideoFrame *resultFrame, int64_t timestamp);
|
||
|
|
||
|
/**
|
||
|
* Reads a frame by its number (index) and returns it.
|
||
|
* @param resultFrame Read frame
|
||
|
* @param frameNumber Frame number (index)
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool get_frame_by_number(VideoFrame *resultFrame, unsigned long frameNumber);
|
||
|
|
||
|
/**
|
||
|
* Reads a frame following to the current one returns it.
|
||
|
* @param resultFrame Read frame
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool get_next_frame(VideoFrame *resultFrame);
|
||
|
|
||
|
/**
|
||
|
* Reads a frame preceding to the current one returns it.
|
||
|
* @param resultFrame Read frame
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool get_previous_frame(VideoFrame *resultFrame);
|
||
|
|
||
|
// reads new frame to this.newFrame
|
||
|
/**
|
||
|
* Reads a new frame from the input video stream. The new frame is stored in resultFrame.
|
||
|
* @param packet Packet structure for storing the read packet; It is also used for returning audio packets
|
||
|
* @param onlyVideoPackets If false - audio packets are read as well as video packets. If true - only video packets are read.
|
||
|
* @param isAudio Is set to true if the function returned an audio packet in AVPacket &packet
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool read_frame(AVPacket &packet, bool onlyVideoPackets=true, bool *isAudio=nullptr);
|
||
|
|
||
|
/**
|
||
|
* Returns the current frame that has already been read.
|
||
|
* @param frame Read frame
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool get_current_frame(VideoFrame *frame);
|
||
|
|
||
|
/**
|
||
|
* Rewinds the video to its beginning by seeking its first packet.
|
||
|
* @return True if successful
|
||
|
*/
|
||
|
bool seek_first_packet();
|
||
|
|
||
|
/**
|
||
|
* Returns the input file format name.
|
||
|
* @return File format name
|
||
|
*/
|
||
|
const char *get_format_name();
|
||
|
|
||
|
private:
|
||
|
/**
|
||
|
* Converts a given frame timestamp to a time position.
|
||
|
* @param timestamp Timestamp
|
||
|
* @return Time position
|
||
|
*/
|
||
|
unsigned long get_time_position_by_timestamp(int64_t timestamp) const; // In miliseconds
|
||
|
|
||
|
/**
|
||
|
* Analyzes the opened video so that it can be seeked
|
||
|
* @param progressDialog QT progress dialog for showing an information about analyzation progress.
|
||
|
*/
|
||
|
void analyze_video(QProgressDialog const *progressDialog);
|
||
|
|
||
|
private:
|
||
|
const int scalingMethod;
|
||
|
int videoStreamID;
|
||
|
int audioStreamID; // -1 => no audio stream found
|
||
|
|
||
|
AVRational timeBase;
|
||
|
|
||
|
AVPacket pkt;
|
||
|
AVFormatContext *formatContext;
|
||
|
AVFrame *newFrame;
|
||
|
AVCodecContext *videoContext;
|
||
|
AVCodecContext *videoContextOrig;
|
||
|
int64_t firstTimestamp;
|
||
|
int64_t firstTimestampSet;
|
||
|
|
||
|
int64_t firstPts;
|
||
|
int64_t firstPtsSet;
|
||
|
int64_t lastTimestamp; // pkt_pts of last successfully read frame
|
||
|
|
||
|
std::vector<int64_t> framesIndexVector;
|
||
|
std::set<int64_t> framesTimestampSet;
|
||
|
};
|
||
|
|
||
|
#endif // FFMPEGPLAYER_H
|