singe/ffms2/src/core/utils.cpp
2019-11-18 20:30:00 -06:00

142 lines
4.9 KiB
C++

// Copyright (c) 2007-2015 Fredrik Mellbin
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
extern "C" {
#include <libavutil/channel_layout.h>
}
#include "utils.h"
#include "indexing.h"
#include "track.h"
#ifdef _WIN32
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif // _WIN32
#include <algorithm>
#include <sstream>
FFMS_Exception::FFMS_Exception(int ErrorType, int SubType, const char *Message) : _Message(Message), _ErrorType(ErrorType), _SubType(SubType) {}
FFMS_Exception::FFMS_Exception(int ErrorType, int SubType, const std::string &Message) : _Message(Message), _ErrorType(ErrorType), _SubType(SubType) {}
int FFMS_Exception::CopyOut(FFMS_ErrorInfo *ErrorInfo) const {
if (ErrorInfo) {
ErrorInfo->ErrorType = _ErrorType;
ErrorInfo->SubType = _SubType;
if (ErrorInfo->BufferSize > 0) {
memset(ErrorInfo->Buffer, 0, ErrorInfo->BufferSize);
_Message.copy(ErrorInfo->Buffer, ErrorInfo->BufferSize - 1);
}
}
return (_ErrorType << 16) | _SubType;
}
void ClearErrorInfo(FFMS_ErrorInfo *ErrorInfo) {
if (ErrorInfo) {
ErrorInfo->ErrorType = FFMS_ERROR_SUCCESS;
ErrorInfo->SubType = FFMS_ERROR_SUCCESS;
if (ErrorInfo->BufferSize > 0)
ErrorInfo->Buffer[0] = 0;
}
}
void InitNullPacket(AVPacket &pkt) {
av_init_packet(&pkt);
pkt.data = nullptr;
pkt.size = 0;
}
void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames) {
AP.SampleFormat = static_cast<FFMS_SampleFormat>(av_get_packed_sample_fmt(CTX->sample_fmt));
AP.BitsPerSample = av_get_bytes_per_sample(CTX->sample_fmt) * 8;
AP.Channels = CTX->channels;
AP.ChannelLayout = CTX->channel_layout;
AP.SampleRate = CTX->sample_rate;
if (!Frames.empty()) {
AP.NumSamples = (Frames.back()).SampleStart + (Frames.back()).SampleCount;
AP.FirstTime = ((Frames.front().PTS * Frames.TB.Num) / (double)Frames.TB.Den) / 1000;
AP.LastTime = ((Frames.back().PTS * Frames.TB.Num) / (double)Frames.TB.Den) / 1000;
AP.LastEndTime = (((Frames.back().PTS + Frames.LastDuration) * Frames.TB.Num) / (double)Frames.TB.Den) / 1000;
}
if (AP.ChannelLayout == 0)
AP.ChannelLayout = av_get_default_channel_layout(AP.Channels);
}
void LAVFOpenFile(const char *SourceFile, AVFormatContext *&FormatContext, int Track) {
if (avformat_open_input(&FormatContext, SourceFile, nullptr, nullptr) != 0)
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ,
std::string("Couldn't open '") + SourceFile + "'");
if (avformat_find_stream_info(FormatContext, nullptr) < 0) {
avformat_close_input(&FormatContext);
FormatContext = nullptr;
throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ,
"Couldn't find stream information");
}
for (int i = 0; i < (int)FormatContext->nb_streams; i++)
if (i != Track)
FormatContext->streams[i]->discard = AVDISCARD_ALL;
}
int ResizerNameToSWSResizer(const char *ResizerName) {
if (!ResizerName)
return 0;
std::string s = ResizerName;
std::transform(s.begin(), s.end(), s.begin(), toupper);
if (s == "FAST_BILINEAR")
return SWS_FAST_BILINEAR;
if (s == "BILINEAR")
return SWS_BILINEAR;
if (s == "BICUBIC")
return SWS_BICUBIC;
if (s == "X")
return SWS_X;
if (s == "POINT")
return SWS_POINT;
if (s == "AREA")
return SWS_AREA;
if (s == "BICUBLIN")
return SWS_BICUBLIN;
if (s == "GAUSS")
return SWS_GAUSS;
if (s == "SINC")
return SWS_SINC;
if (s == "LANCZOS")
return SWS_LANCZOS;
if (s == "SPLINE")
return SWS_SPLINE;
return 0;
}
bool IsSamePath(const char *p1, const char *p2) {
// assume windows is the only OS with a case insensitive filesystem and ignore all path complications
#ifndef _WIN32
return !strcmp(p1, p2);
#else
return !_stricmp(p1, p2);
#endif
}