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

//------------------------------------------------------------------------------
//
// 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