Compare commits
36 Commits
libvpx-vp9
...
0.2.0pre3
| Author | SHA1 | Date | |
|---|---|---|---|
| 60e5499d3d | |||
| d4ffd20085 | |||
| c3d1793f14 | |||
| 57ebb9d866 | |||
| 9f8e4b67c6 | |||
| c61b2aead1 | |||
| f7db2d45af | |||
| 2840a7fbb1 | |||
| 51a5396fb1 | |||
| 9db2219582 | |||
| 68bacc07dc | |||
| fa5c421d34 | |||
| d178200800 | |||
| ac68c2f4c8 | |||
| a5d14c87ff | |||
| de1a687b8d | |||
| 855b3571b1 | |||
| c053933c25 | |||
| e1fbfd707c | |||
| 69f7afef1f | |||
| 5ba4694890 | |||
| e579b10dcd | |||
| f530f9ee9f | |||
| 8b429db62e | |||
| 6851f2321a | |||
| 2472668f1d | |||
| 6eadcfe821 | |||
| 7663a25bb3 | |||
| 38f154531c | |||
| 666fe5fdfb | |||
| f744b1e9cb | |||
| 9552d12ee8 | |||
| f15769ddb7 | |||
| 8b80dc57ad | |||
| 83c9de95f9 | |||
| a298680e07 |
@@ -0,0 +1,3 @@
|
|||||||
|
issuehunt: xaymar
|
||||||
|
patreon: xaymar
|
||||||
|
custom: https://www.paypal.me/xaymar
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Want a new feature implemented?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--- Please fill out the following template, which will help other contributors review your Issue. -->
|
||||||
|
<!--- Make sure you’ve read the contribution guidelines -->
|
||||||
|
|
||||||
|
### Description
|
||||||
|
<!-- Describe the feature (and behavior) in as much detail as possible (yes, that means write an essay if you have to) -->
|
||||||
|
<!-- Include images of what you expect from the feature -->
|
||||||
|
|
||||||
|
### Checklist:
|
||||||
|
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||||
|
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||||
|
- [ ] I have read the contribution guidelines.
|
||||||
|
- [ ] This feature is necessary and can't be done through other means.
|
||||||
|
- [ ] This feature does not break existing functionality.
|
||||||
|
- [ ] I am willing to hire/pay someone to implement this.
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
name: Question/Feedback
|
||||||
|
about: Submit a question or some feedback! (Not for bugs, issues or crashes!)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--- Please fill out the following template, which will help other contributors review your Issue. -->
|
||||||
|
<!--- Make sure you’ve read the contribution guidelines -->
|
||||||
|
|
||||||
|
### Description
|
||||||
|
<!-- Describe the feature (and behavior) in as much detail as possible (yes, that means write an essay if you have to) -->
|
||||||
|
<!-- Include images of what you expect from the feature -->
|
||||||
|
|
||||||
|
### System Information
|
||||||
|
<!-- Include as much information about the system you're using as possible. -->
|
||||||
|
- Software Version: [e. g. 1.0.0, 1.2.1, ... - NEVER LATEST]
|
||||||
|
- Operating System: [e. g. Windows, Debian, Ubuntu, RedHat, FreeBSD, ...]
|
||||||
|
- Kernel Version: [e. g. 1903/1809 (Windows), 4.12 (Linux), ...]
|
||||||
|
- CPU: [e. g. Intel i7, AMD Zen2, Qualcomm, ...]
|
||||||
|
- GPU: [e. g. Nvidia RTX 2xxx Series, AMD Radeone 5xxx Series, ...]
|
||||||
|
- RAM: [e. g. 16GB, 32GB, 64GB, ...]
|
||||||
|
|
||||||
|
### Checklist:
|
||||||
|
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||||
|
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||||
|
- [ ] I have read the contribution guidelines.
|
||||||
|
- [ ] This is not a bug, crash or generic issue.
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
name: Issue/Bug report
|
||||||
|
about: Encountered a problem, a bug or a crash?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--- Please fill out the following template, which will help other contributors review your Issue. -->
|
||||||
|
<!--- Make sure you’ve read the contribution guidelines -->
|
||||||
|
|
||||||
|
### Description
|
||||||
|
<!-- Describe the bug (and behavior) in as much detail as necessary -->
|
||||||
|
<!-- Include screenshots and attach (crash) logs if possible -->
|
||||||
|
|
||||||
|
### Expected Behavior
|
||||||
|
<!-- What is the expected behavior in this case? -->
|
||||||
|
|
||||||
|
### Reproduction Steps
|
||||||
|
<!-- Describe the steps required to get this to happen from a cleanly installed obs-studio -->
|
||||||
|
<!-- Leave out detail that is not relevant to -->
|
||||||
|
1. Open a portal to the Infinite Void
|
||||||
|
2. Summon an ancient God
|
||||||
|
3. Realize your mistake
|
||||||
|
|
||||||
|
### System Information
|
||||||
|
<!-- Include as much information about the system you're using as possible. -->
|
||||||
|
- Software Version: [e. g. 1.0.0, 1.2.1, ... - NEVER LATEST]
|
||||||
|
- Operating System: [e. g. Windows, Debian, Ubuntu, RedHat, FreeBSD, ...]
|
||||||
|
- Kernel Version: [e. g. 1903/1809 (Windows), 4.12 (Linux), ...]
|
||||||
|
- CPU: [e. g. Intel i7, AMD Zen2, Qualcomm, ...]
|
||||||
|
- GPU: [e. g. Nvidia RTX 2xxx Series, AMD Radeone 5xxx Series, ...]
|
||||||
|
- RAM: [e. g. 16GB, 32GB, 64GB, ...]
|
||||||
|
|
||||||
|
### Checklist:
|
||||||
|
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||||
|
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||||
|
- [ ] I have read the contribution guidelines.
|
||||||
|
- [ ] I can reproduce the issue with the exact reproduction steps I have provided.
|
||||||
|
- [ ] The issue appears on all of my systems that can run this software.
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<!--- Please fill out the following template, which will help other contributors review your Pull Request. -->
|
||||||
|
|
||||||
|
<!--- Make sure you’ve read the contribution guidelines -->
|
||||||
|
|
||||||
|
### Description
|
||||||
|
<!--- Describe your changes in detail. -->
|
||||||
|
<!--- If this change includes UI elements, please include screenshots. -->
|
||||||
|
|
||||||
|
### Motivation and Context
|
||||||
|
<!--- Why is this change required? What problem does it solve? -->
|
||||||
|
<!--- If it fixes an open Mantis issue, or implements feature request -->
|
||||||
|
<!--- from the Ideas page, please link to the issue here. -->
|
||||||
|
|
||||||
|
### How Has This Been Tested?
|
||||||
|
<!--- Please describe in detail how you tested your changes. -->
|
||||||
|
<!--- Include details of your testing environment (hardware, OS version, etc.),-->
|
||||||
|
<!--- and the tests you ran, including how it may affect other areas of code. -->
|
||||||
|
|
||||||
|
### Types of changes
|
||||||
|
<!--- What types of changes does your PR introduce? Uncomment all that apply -->
|
||||||
|
<!--- - Bug fix (non-breaking change which fixes an issue) -->
|
||||||
|
<!--- - New feature (non-breaking change which adds functionality) -->
|
||||||
|
<!--- - Performance enhancement (non-breaking change which improves efficiency) -->
|
||||||
|
<!--- - Code cleanup (non-breaking change which makes code smaller or more readable) -->
|
||||||
|
<!--- - Breaking change (fix or feature that would cause existing functionality to change) -->
|
||||||
|
<!--- - Documentation (a change to documentation pages) -->
|
||||||
|
|
||||||
|
### Checklist:
|
||||||
|
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||||
|
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||||
|
- [ ] My code has been run through [clang-format](https://github.com/obsproject/obs-studio/blob/master/.clang-format).
|
||||||
|
- [ ] I have read the [**contributing** document](https://github.com/obsproject/obs-studio/blob/master/CONTRIBUTING.rst).
|
||||||
|
- [ ] My code is not on the master branch.
|
||||||
|
- [ ] The code has been tested.
|
||||||
|
- [ ] All commit messages are properly formatted and commits squashed where appropriate.
|
||||||
+27
-13
@@ -1,19 +1,23 @@
|
|||||||
# Integrates most FFmpeg supported encoders into OBS Studio
|
# FFMPEG Video Encoder Integration for OBS Studio
|
||||||
# Copyright (C) 2018 - 2019 Michael Fabian Dirks
|
# Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# it under the terms of the GNU General Public License as published by
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
# in the Software without restriction, including without limitation the rights
|
||||||
# (at your option) any later version.
|
# 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:
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# The above copyright notice and this permission notice shall be included in all
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# copies or substantial portions of the Software.
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
# along with this program; if not, write to the Free Software
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
# 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.
|
||||||
|
|
||||||
# CMake Setup
|
# CMake Setup
|
||||||
CMake_Minimum_Required(VERSION 3.8.0)
|
CMake_Minimum_Required(VERSION 3.8.0)
|
||||||
@@ -264,6 +268,10 @@ set(PROJECT_PRIVATE
|
|||||||
"${PROJECT_SOURCE_DIR}/source/utility.cpp"
|
"${PROJECT_SOURCE_DIR}/source/utility.cpp"
|
||||||
"${PROJECT_SOURCE_DIR}/source/utility.hpp"
|
"${PROJECT_SOURCE_DIR}/source/utility.hpp"
|
||||||
"${PROJECT_SOURCE_DIR}/source/strings.hpp"
|
"${PROJECT_SOURCE_DIR}/source/strings.hpp"
|
||||||
|
"${PROJECT_SOURCE_DIR}/source/codecs/hevc.hpp"
|
||||||
|
"${PROJECT_SOURCE_DIR}/source/codecs/hevc.cpp"
|
||||||
|
"${PROJECT_SOURCE_DIR}/source/codecs/h264.hpp"
|
||||||
|
"${PROJECT_SOURCE_DIR}/source/codecs/h264.cpp"
|
||||||
"${PROJECT_SOURCE_DIR}/source/encoders/generic.hpp"
|
"${PROJECT_SOURCE_DIR}/source/encoders/generic.hpp"
|
||||||
"${PROJECT_SOURCE_DIR}/source/encoders/generic.cpp"
|
"${PROJECT_SOURCE_DIR}/source/encoders/generic.cpp"
|
||||||
"${PROJECT_SOURCE_DIR}/source/encoders/prores_aw.hpp"
|
"${PROJECT_SOURCE_DIR}/source/encoders/prores_aw.hpp"
|
||||||
@@ -280,6 +288,12 @@ set(PROJECT_PRIVATE
|
|||||||
"${PROJECT_SOURCE_DIR}/source/ui/debug_handler.cpp"
|
"${PROJECT_SOURCE_DIR}/source/ui/debug_handler.cpp"
|
||||||
"${PROJECT_SOURCE_DIR}/source/ui/prores_aw_handler.hpp"
|
"${PROJECT_SOURCE_DIR}/source/ui/prores_aw_handler.hpp"
|
||||||
"${PROJECT_SOURCE_DIR}/source/ui/prores_aw_handler.cpp"
|
"${PROJECT_SOURCE_DIR}/source/ui/prores_aw_handler.cpp"
|
||||||
|
"${PROJECT_SOURCE_DIR}/source/ui/nvenc_shared.hpp"
|
||||||
|
"${PROJECT_SOURCE_DIR}/source/ui/nvenc_shared.cpp"
|
||||||
|
"${PROJECT_SOURCE_DIR}/source/ui/nvenc_h264_handler.hpp"
|
||||||
|
"${PROJECT_SOURCE_DIR}/source/ui/nvenc_h264_handler.cpp"
|
||||||
|
"${PROJECT_SOURCE_DIR}/source/ui/nvenc_hevc_handler.hpp"
|
||||||
|
"${PROJECT_SOURCE_DIR}/source/ui/nvenc_hevc_handler.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Source Grouping
|
# Source Grouping
|
||||||
|
|||||||
@@ -1,278 +1,21 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
MIT License
|
||||||
Version 2, June 1991
|
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
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 licenses for most software are designed to take away your
|
The above copyright notice and this permission notice shall be included in all
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
copies or substantial portions of the Software.
|
||||||
License is intended to guarantee your freedom to share and change free
|
|
||||||
software--to make sure the software is free for all its users. This
|
|
||||||
General Public License applies to most of the Free Software
|
|
||||||
Foundation's software and to any other program whose authors commit to
|
|
||||||
using it. (Some other Free Software Foundation software is covered by
|
|
||||||
the GNU Library General Public License instead.) You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
have the freedom to distribute copies of free software (and charge for
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
this service if you wish), that you receive source code or can get it
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
if you want it, that you can change the software or use pieces of it
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
in new free programs; and that you know you can do these things.
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
anyone to deny you these rights or to ask you to surrender the rights.
|
|
||||||
These restrictions translate to certain responsibilities for you if you
|
|
||||||
distribute copies of the software, or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must give the recipients all the rights that
|
|
||||||
you have. You must make sure that they, too, receive or can get the
|
|
||||||
source code. And you must show them these terms so they know their
|
|
||||||
rights.
|
|
||||||
|
|
||||||
We protect your rights with two steps: (1) copyright the software, and
|
|
||||||
(2) offer you this license which gives you legal permission to copy,
|
|
||||||
distribute and/or modify the software.
|
|
||||||
|
|
||||||
Also, for each author's protection and ours, we want to make certain
|
|
||||||
that everyone understands that there is no warranty for this free
|
|
||||||
software. If the software is modified by someone else and passed on, we
|
|
||||||
want its recipients to know that what they have is not the original, so
|
|
||||||
that any problems introduced by others will not reflect on the original
|
|
||||||
authors' reputations.
|
|
||||||
|
|
||||||
Finally, any free program is threatened constantly by software
|
|
||||||
patents. We wish to avoid the danger that redistributors of a free
|
|
||||||
program will individually obtain patent licenses, in effect making the
|
|
||||||
program proprietary. To prevent this, we have made it clear that any
|
|
||||||
patent must be licensed for everyone's free use or not licensed at all.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License applies to any program or other work which contains
|
|
||||||
a notice placed by the copyright holder saying it may be distributed
|
|
||||||
under the terms of this General Public License. The "Program", below,
|
|
||||||
refers to any such program or work, and a "work based on the Program"
|
|
||||||
means either the Program or any derivative work under copyright law:
|
|
||||||
that is to say, a work containing the Program or a portion of it,
|
|
||||||
either verbatim or with modifications and/or translated into another
|
|
||||||
language. (Hereinafter, translation is included without limitation in
|
|
||||||
the term "modification".) Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running the Program is not restricted, and the output from the Program
|
|
||||||
is covered only if its contents constitute a work based on the
|
|
||||||
Program (independent of having been made by running the Program).
|
|
||||||
Whether that is true depends on what the Program does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Program's
|
|
||||||
source code as you receive it, in any medium, provided that you
|
|
||||||
conspicuously and appropriately publish on each copy an appropriate
|
|
||||||
copyright notice and disclaimer of warranty; keep intact all the
|
|
||||||
notices that refer to this License and to the absence of any warranty;
|
|
||||||
and give any other recipients of the Program a copy of this License
|
|
||||||
along with the Program.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy, and
|
|
||||||
you may at your option offer warranty protection in exchange for a fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Program or any portion
|
|
||||||
of it, thus forming a work based on the Program, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) You must cause the modified files to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
b) You must cause any work that you distribute or publish, that in
|
|
||||||
whole or in part contains or is derived from the Program or any
|
|
||||||
part thereof, to be licensed as a whole at no charge to all third
|
|
||||||
parties under the terms of this License.
|
|
||||||
|
|
||||||
c) If the modified program normally reads commands interactively
|
|
||||||
when run, you must cause it, when started running for such
|
|
||||||
interactive use in the most ordinary way, to print or display an
|
|
||||||
announcement including an appropriate copyright notice and a
|
|
||||||
notice that there is no warranty (or else, saying that you provide
|
|
||||||
a warranty) and that users may redistribute the program under
|
|
||||||
these conditions, and telling the user how to view a copy of this
|
|
||||||
License. (Exception: if the Program itself is interactive but
|
|
||||||
does not normally print such an announcement, your work based on
|
|
||||||
the Program is not required to print an announcement.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Program,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Program, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Program.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Program
|
|
||||||
with the Program (or with a work based on the Program) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may copy and distribute the Program (or a work based on it,
|
|
||||||
under Section 2) in object code or executable form under the terms of
|
|
||||||
Sections 1 and 2 above provided that you also do one of the following:
|
|
||||||
|
|
||||||
a) Accompany it with the complete corresponding machine-readable
|
|
||||||
source code, which must be distributed under the terms of Sections
|
|
||||||
1 and 2 above on a medium customarily used for software interchange; or,
|
|
||||||
|
|
||||||
b) Accompany it with a written offer, valid for at least three
|
|
||||||
years, to give any third party, for a charge no more than your
|
|
||||||
cost of physically performing source distribution, a complete
|
|
||||||
machine-readable copy of the corresponding source code, to be
|
|
||||||
distributed under the terms of Sections 1 and 2 above on a medium
|
|
||||||
customarily used for software interchange; or,
|
|
||||||
|
|
||||||
c) Accompany it with the information you received as to the offer
|
|
||||||
to distribute corresponding source code. (This alternative is
|
|
||||||
allowed only for noncommercial distribution and only if you
|
|
||||||
received the program in object code or executable form with such
|
|
||||||
an offer, in accord with Subsection b above.)
|
|
||||||
|
|
||||||
The source code for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For an executable work, complete source
|
|
||||||
code means all the source code for all modules it contains, plus any
|
|
||||||
associated interface definition files, plus the scripts used to
|
|
||||||
control compilation and installation of the executable. However, as a
|
|
||||||
special exception, the source code distributed need not include
|
|
||||||
anything that is normally distributed (in either source or binary
|
|
||||||
form) with the major components (compiler, kernel, and so on) of the
|
|
||||||
operating system on which the executable runs, unless that component
|
|
||||||
itself accompanies the executable.
|
|
||||||
|
|
||||||
If distribution of executable or object code is made by offering
|
|
||||||
access to copy from a designated place, then offering equivalent
|
|
||||||
access to copy the source code from the same place counts as
|
|
||||||
distribution of the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
4. You may not copy, modify, sublicense, or distribute the Program
|
|
||||||
except as expressly provided under this License. Any attempt
|
|
||||||
otherwise to copy, modify, sublicense or distribute the Program is
|
|
||||||
void, and will automatically terminate your rights under this License.
|
|
||||||
However, parties who have received copies, or rights, from you under
|
|
||||||
this License will not have their licenses terminated so long as such
|
|
||||||
parties remain in full compliance.
|
|
||||||
|
|
||||||
5. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Program or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Program (or any work based on the
|
|
||||||
Program), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Program or works based on it.
|
|
||||||
|
|
||||||
6. Each time you redistribute the Program (or any work based on the
|
|
||||||
Program), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute or modify the Program subject to
|
|
||||||
these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties to
|
|
||||||
this License.
|
|
||||||
|
|
||||||
7. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Program at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Program by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Program.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under
|
|
||||||
any particular circumstance, the balance of the section is intended to
|
|
||||||
apply and the section as a whole is intended to apply in other
|
|
||||||
circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system, which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
8. If the distribution and/or use of the Program is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Program under this License
|
|
||||||
may add an explicit geographical distribution limitation excluding
|
|
||||||
those countries, so that distribution is permitted only in or among
|
|
||||||
countries not thus excluded. In such case, this License incorporates
|
|
||||||
the limitation as if written in the body of this License.
|
|
||||||
|
|
||||||
9. The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
|
||||||
specifies a version number of this License which applies to it and "any
|
|
||||||
later version", you have the option of following the terms and conditions
|
|
||||||
either of that version or of any later version published by the Free
|
|
||||||
Software Foundation. If the Program does not specify a version number of
|
|
||||||
this License, you may choose any version ever published by the Free Software
|
|
||||||
Foundation.
|
|
||||||
|
|
||||||
10. If you wish to incorporate parts of the Program into other free
|
|
||||||
programs whose distribution conditions are different, write to the author
|
|
||||||
to ask for permission. For software which is copyrighted by the Free
|
|
||||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
|
||||||
make exceptions for this. Our decision will be guided by the two goals
|
|
||||||
of preserving the free status of all derivatives of our free software and
|
|
||||||
of promoting the sharing and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
|
||||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
|
||||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
|
||||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
|
||||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
|
||||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
|
||||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
|
||||||
REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
|
||||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
|
||||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
|
||||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
|
||||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
|
||||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
|
||||||
POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
+126
-20
@@ -1,11 +1,9 @@
|
|||||||
# ProRes
|
|
||||||
ProRes.Profile.Proxy="Proxy (PXY)"
|
|
||||||
ProRes.Profile.Light="Light (LT)"
|
|
||||||
ProRes.Profile.Standard="Standard"
|
|
||||||
ProRes.Profile.HighQuality="High Quality (HQ)"
|
|
||||||
|
|
||||||
# Generic
|
# Generic
|
||||||
Automatic="Automatic"
|
State.Automatic="Automatic"
|
||||||
|
State.Default="Default"
|
||||||
|
State.Disabled="Disabled"
|
||||||
|
State.Enabled="Enabled"
|
||||||
|
State.Manual="Manual"
|
||||||
|
|
||||||
# FFmpeg
|
# FFmpeg
|
||||||
FFmpeg="FFmpeg Options"
|
FFmpeg="FFmpeg Options"
|
||||||
@@ -25,19 +23,30 @@ FFmpeg.StandardCompliance.Experimental="Experimental"
|
|||||||
|
|
||||||
# Rate Control
|
# Rate Control
|
||||||
RateControl="Rate Control"
|
RateControl="Rate Control"
|
||||||
RateControl.Method="Method"
|
RateControl.Mode="Method"
|
||||||
RateControl.Method.ConstantBitrate="Constant Bitrate (CBR)"
|
RateControl.Mode.ConstantBitrate="Constant Bitrate"
|
||||||
RateControl.Method.AverageBitrate="Average Bitrate (ABR)"
|
RateControl.Mode.AverageBitrate="Average Bitrate"
|
||||||
RateControl.Method.VariableBitrate="Variable Bitrate (VBR)"
|
RateControl.Mode.VariableBitrate="Variable Bitrate"
|
||||||
RateControl.Method.ConstantQuantizationParameter="Constant Quantization Parameter (CQP)"
|
RateControl.Mode.ConstantQuantizationParameter="Constant Quantization Parameter"
|
||||||
RateControl.Method.ConstantRateFactor="Constant Rate Factor (CRF)"
|
RateControl.Mode.ConstantRateFactor="Constant Rate Factor"
|
||||||
RateControl.Method.ConstantQuality="Constant Quality (CQ)"
|
RateControl.Mode.ConstantQuality="Constant Quality"
|
||||||
RateControl.Method.VariableQuality="Variable Quality (VQ)"
|
RateControl.Mode.VariableQuality="Variable Quality"
|
||||||
RateControl.Method.Lossless="Lossless (LL)"
|
RateControl.Mode.Lossless="Lossless"
|
||||||
RateControl.Bitrate.Target="Target Bitrate (kbit/s)"
|
RateControl.Bitrate.Target="Target Bitrate"
|
||||||
RateControl.Bitrate.Minimum="Minimum Bitrate (kbit/s)"
|
RateControl.Bitrate.Minimum="Minimum Bitrate"
|
||||||
RateControl.Bitrate.Maximum="Maximum Bitrate (kbit/s)"
|
RateControl.Bitrate.Maximum="Maximum Bitrate"
|
||||||
RateControl.BufferSize="Buffer Size (kbit/s)"
|
RateControl.Quality.Target="Target Quality"
|
||||||
|
RateControl.Quality.Minimum="Minimum Quality"
|
||||||
|
RateControl.Quality.Maximum="Maximum Quality"
|
||||||
|
RateControl.BufferSize="Buffer Size"
|
||||||
|
RateControl.BufferSize.Description="The size of the buffer to use when determining the remaining available bitrate.\nIdeally should be equal to your bitrate times the key frame interval in seconds."
|
||||||
|
|
||||||
|
# Key Frames
|
||||||
|
KeyFrames="Key Frames"
|
||||||
|
KeyFrames.IntervalType="Interval Type"
|
||||||
|
KeyFrames.IntervalType.Frames="Frames"
|
||||||
|
KeyFrames.IntervalType.Seconds="Seconds"
|
||||||
|
KeyFrames.Interval="Interval"
|
||||||
|
|
||||||
# Apple ProRes
|
# Apple ProRes
|
||||||
AppleProRes.Profile="Profile"
|
AppleProRes.Profile="Profile"
|
||||||
@@ -46,3 +55,100 @@ AppleProRes.Profile.APCS="LT"
|
|||||||
AppleProRes.Profile.APCN="Standard Definition"
|
AppleProRes.Profile.APCN="Standard Definition"
|
||||||
AppleProRes.Profile.APCH="High Quality"
|
AppleProRes.Profile.APCH="High Quality"
|
||||||
AppleProRes.Profile.AP4H="4444"
|
AppleProRes.Profile.AP4H="4444"
|
||||||
|
|
||||||
|
# ProRes
|
||||||
|
ProRes.Profile.Proxy="Proxy (PXY)"
|
||||||
|
ProRes.Profile.Light="Light (LT)"
|
||||||
|
ProRes.Profile.Standard="Standard"
|
||||||
|
ProRes.Profile.HighQuality="High Quality (HQ)"
|
||||||
|
|
||||||
|
# Codec: H264
|
||||||
|
Codec.H264="H264"
|
||||||
|
Codec.H264.Profile="Profile"
|
||||||
|
Codec.H264.Profile.baseline="Baseline"
|
||||||
|
Codec.H264.Profile.main="Main"
|
||||||
|
Codec.H264.Profile.high="High"
|
||||||
|
Codec.H264.Profile.high444p="High 4:4:4 Predictive"
|
||||||
|
Codec.H264.Level="Level"
|
||||||
|
|
||||||
|
# Codec: HEVC
|
||||||
|
Codec.HEVC="HEVC"
|
||||||
|
Codec.HEVC.Profile="Profile"
|
||||||
|
Codec.HEVC.Profile.main="Main"
|
||||||
|
Codec.HEVC.Profile.main10="Main 10-bit"
|
||||||
|
Codec.HEVC.Profile.rext="Range Extended"
|
||||||
|
Codec.HEVC.Tier="Tier"
|
||||||
|
Codec.HEVC.Tier.main="Main"
|
||||||
|
Codec.HEVC.Tier.high="High"
|
||||||
|
Codec.HEVC.Level="Level"
|
||||||
|
|
||||||
|
# NVENC
|
||||||
|
NVENC.Preset="Preset"
|
||||||
|
NVENC.Preset.Default="Default"
|
||||||
|
NVENC.Preset.Slow="Slow"
|
||||||
|
NVENC.Preset.Medium="Medium"
|
||||||
|
NVENC.Preset.Fast="Fast"
|
||||||
|
NVENC.Preset.HighPerformance="High Performance"
|
||||||
|
NVENC.Preset.HighQuality="High Quality"
|
||||||
|
NVENC.Preset.BluRayDisc="BluRay Disc"
|
||||||
|
NVENC.Preset.LowLatency="Low Latency"
|
||||||
|
NVENC.Preset.LowLatencyHighPerformance="Low Latency High Performance"
|
||||||
|
NVENC.Preset.LowLatencyHighQuality="Low Latency High Quality"
|
||||||
|
NVENC.Preset.Lossless="Lossless"
|
||||||
|
NVENC.Preset.LosslessHighPerformance="Lossless High Performance"
|
||||||
|
NVENC.RateControl="Rate Control Options"
|
||||||
|
NVENC.RateControl.Mode="Mode"
|
||||||
|
NVENC.RateControl.Mode.CQP="Constant Quantization Parameter"
|
||||||
|
NVENC.RateControl.Mode.VBR="Variable Bitrate"
|
||||||
|
NVENC.RateControl.Mode.VBR_HQ="High Quality Variable Bitrate"
|
||||||
|
NVENC.RateControl.Mode.CBR="Constant Bitrate"
|
||||||
|
NVENC.RateControl.Mode.CBR_HQ="High Quality Constant Bitrate"
|
||||||
|
NVENC.RateControl.Mode.CBR_LD_HQ="Low Delay High Quality Constant Bitrate"
|
||||||
|
NVENC.RateControl.LookAhead="Look Ahead"
|
||||||
|
NVENC.RateControl.LookAhead.Description="Look ahead this many frames while encoding to better distribute bitrate.\nImproves quality slightly at the cost of some GPU time.\nSet to 0 to disable."
|
||||||
|
NVENC.RateControl.AdaptiveI="Enable adaptive I-Frame insertion"
|
||||||
|
NVENC.RateControl.AdaptiveI.Description="Enables adaptive I-Frame insertion.\nOnly has an effect when look ahead is set to a value other than 0."
|
||||||
|
NVENC.RateControl.AdaptiveB="Enable adaptive B-Frame insertion"
|
||||||
|
NVENC.RateControl.AdaptiveB.Description="Enables adaptive B-Frame insertion.\nOnly has an effect when look ahead is set to a value other than 0."
|
||||||
|
NVENC.RateControl.TwoPass="Enable Two Pass"
|
||||||
|
NVENC.RateControl.TwoPass.Description="Enable a secondary pass for encoding, which can help with quality and bitrate stability.\nImproves quality slightly at the cost of some GPU time.\nNvidia Turing hardware might actually see a quality degrade from this."
|
||||||
|
NVENC.RateControl.Bitrate="Bitrate Limits"
|
||||||
|
NVENC.RateControl.Bitrate.Target="Target Bitrate"
|
||||||
|
NVENC.RateControl.Bitrate.Maximum="Maximum Bitrate"
|
||||||
|
NVENC.RateControl.Quality="Enable Quality Limits"
|
||||||
|
NVENC.RateControl.Quality.Minimum="Minimum Quality"
|
||||||
|
NVENC.RateControl.Quality.Minimum.Description="Minimum quality to achieve, with values closer to 0 being better quality."
|
||||||
|
NVENC.RateControl.Quality.Maximum="Maximum Quality"
|
||||||
|
NVENC.RateControl.Quality.Maximum.Description="Maximum quality to achieve, with values closer to 0 being better quality.\nSet to -1 to disable the maximum restriction."
|
||||||
|
NVENC.RateControl.QP="Quantization Parameters"
|
||||||
|
NVENC.RateControl.QP.I="I-Frame QP"
|
||||||
|
NVENC.RateControl.QP.I.Description="Quantization parameter for I-Frames.\nSmaller values mean better quality in exchange for higher bitrate, while higher values mean less bitrate in exchange for less quality."
|
||||||
|
NVENC.RateControl.QP.I.Initial="Initial I-Frame QP"
|
||||||
|
NVENC.RateControl.QP.I.Initial.Description="Initial B-Frame quantization parameter.\nSet to -1 to use the automatically detected value instead."
|
||||||
|
NVENC.RateControl.QP.P="P-Frame QP"
|
||||||
|
NVENC.RateControl.QP.P.Description="Quantization parameter for P-Frames.\nSmaller values mean better quality in exchange for higher bitrate, while higher values mean less bitrate in exchange for less quality."
|
||||||
|
NVENC.RateControl.QP.P.Initial="Initial P-Frame QP"
|
||||||
|
NVENC.RateControl.QP.P.Initial.Description="Initial P-Frame quantization parameter.\nSet to -1 to use the automatically detected value instead."
|
||||||
|
NVENC.RateControl.QP.B="B-Frame QP"
|
||||||
|
NVENC.RateControl.QP.B.Description="Quantization parameter for B-Frames.\nSmaller values mean better quality in exchange for higher bitrate, while higher values mean less bitrate in exchange for less quality."
|
||||||
|
NVENC.RateControl.QP.B.Initial="Initial B-Frame QP"
|
||||||
|
NVENC.RateControl.QP.B.Initial.Description="Initial B-Frame quantization parameter.\nSet to -1 to use the automatically detected value instead."
|
||||||
|
NVENC.AQ="Adaptive Quantization"
|
||||||
|
NVENC.AQ.Spatial="Enable Spatial Adaptive Quantization"
|
||||||
|
NVENC.AQ.Spatial.Description="Enable spatial adaptive quantization, also sometimes referred to as Psychovisual Adaptive Quantization."
|
||||||
|
NVENC.AQ.Strength="Spatial AQ Strength"
|
||||||
|
NVENC.AQ.Strength.Description="Strength of the spatial adaptive quantization.\nValues closer to 15 mean more aggressive, while values closer to 1 mean more relaxed."
|
||||||
|
NVENC.AQ.Temporal="Enable Temporal Adaptive Quantization"
|
||||||
|
NVENC.AQ.Temporal.Description="Enable temporal adaptive quantization."
|
||||||
|
NVENC.Other="Other Options"
|
||||||
|
NVENC.Other.BFrames="Maximum B-Frames"
|
||||||
|
NVENC.Other.BFrames.Description="Maximum number of B-Frames to insert into the encoded bitstream.\nActual number of B-Frames may be lower depending on content and lookahead settings."
|
||||||
|
NVENC.Other.BFrameReferenceMode="B-Frame Reference Mode"
|
||||||
|
NVENC.Other.BFrameReferenceMode.Each="Each B-Frame will be used for references"
|
||||||
|
NVENC.Other.BFrameReferenceMode.Middle="Only (# of B-Frames)/2 will be used for references"
|
||||||
|
NVENC.Other.ZeroLatency="Enable Zero Latency"
|
||||||
|
NVENC.Other.ZeroLatency.Description="Enable zero latency operation, which ensures that there is no reordering delay."
|
||||||
|
NVENC.Other.WeightedPrediction="Enable Weighted Prediction"
|
||||||
|
NVENC.Other.WeightedPrediction.Description="Enable weighted prediction for encoding.\nCan't be used with B-Frames."
|
||||||
|
NVENC.Other.NonReferencePFrames="Enable non-reference P-Frames"
|
||||||
|
NVENC.Other.NonReferencePFrames.Description="Enable the automatic insertion of non-reference P-Frames."
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#include "h264.hpp"
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
// Codec: H264
|
||||||
|
#define P_H264 "Codec.H264"
|
||||||
|
#define P_H264_PROFILE "Codec.H264.Profile"
|
||||||
|
#define P_H264_LEVEL "Codec.H264.Level"
|
||||||
|
|
||||||
|
namespace obsffmpeg {
|
||||||
|
namespace codecs {
|
||||||
|
namespace h264 {
|
||||||
|
enum class profile {
|
||||||
|
CONSTRAINED_BASELINE,
|
||||||
|
BASELINE,
|
||||||
|
MAIN,
|
||||||
|
HIGH,
|
||||||
|
HIGH444_PREDICTIVE,
|
||||||
|
UNKNOWN = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class level {
|
||||||
|
L1_0 = 10,
|
||||||
|
L1_0b,
|
||||||
|
L1_1,
|
||||||
|
L1_2,
|
||||||
|
L1_3,
|
||||||
|
L2_0 = 20,
|
||||||
|
L2_1,
|
||||||
|
L2_2,
|
||||||
|
L3_0 = 30,
|
||||||
|
L3_1,
|
||||||
|
L3_2,
|
||||||
|
L4_0 = 40,
|
||||||
|
L4_1,
|
||||||
|
L4_2,
|
||||||
|
L5_0 = 50,
|
||||||
|
L5_1,
|
||||||
|
L5_2,
|
||||||
|
L6_0 = 60,
|
||||||
|
L6_1,
|
||||||
|
L6_2,
|
||||||
|
UNKNOWN = -1,
|
||||||
|
};
|
||||||
|
} // namespace h264
|
||||||
|
} // namespace codecs
|
||||||
|
} // namespace obsffmpeg
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#include "hevc.hpp"
|
||||||
|
|
||||||
|
using namespace obsffmpeg::codecs::hevc;
|
||||||
|
|
||||||
|
std::map<profile, std::string> obsffmpeg::codecs::hevc::profiles{
|
||||||
|
{profile::MAIN, "main"},
|
||||||
|
{profile::MAIN10, "main10"},
|
||||||
|
{profile::RANGE_EXTENDED, "rext"},
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<tier, std::string> obsffmpeg::codecs::hevc::profile_tiers{
|
||||||
|
{tier::MAIN, "main"},
|
||||||
|
{tier::HIGH, "high"},
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<level, std::string> obsffmpeg::codecs::hevc::levels{
|
||||||
|
{level::L1_0, "1.0"}, {level::L2_0, "2.0"}, {level::L3_0, "3.0"}, {level::L3_1, "3.1"},
|
||||||
|
{level::L4_0, "4.0"}, {level::L4_1, "4.1"}, {level::L5_0, "5.0"}, {level::L5_1, "5.1"},
|
||||||
|
{level::L5_2, "5.2"}, {level::L6_0, "6.0"}, {level::L6_1, "6.1"}, {level::L6_2, "6.2"},
|
||||||
|
};
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
// Codec: HEVC
|
||||||
|
#define P_HEVC "Codec.HEVC"
|
||||||
|
#define P_HEVC_PROFILE "Codec.HEVC.Profile"
|
||||||
|
#define P_HEVC_TIER "Codec.HEVC.Tier"
|
||||||
|
#define P_HEVC_LEVEL "Codec.HEVC.Level"
|
||||||
|
|
||||||
|
namespace obsffmpeg {
|
||||||
|
namespace codecs {
|
||||||
|
namespace hevc {
|
||||||
|
enum class profile {
|
||||||
|
MAIN,
|
||||||
|
MAIN10,
|
||||||
|
RANGE_EXTENDED,
|
||||||
|
UNKNOWN = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class tier {
|
||||||
|
MAIN,
|
||||||
|
HIGH,
|
||||||
|
UNKNOWN = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class level {
|
||||||
|
L1_0 = 30,
|
||||||
|
L2_0 = 60,
|
||||||
|
L3_0 = 90,
|
||||||
|
L3_1 = 93,
|
||||||
|
L4_0 = 120,
|
||||||
|
L4_1 = 123,
|
||||||
|
L5_0 = 150,
|
||||||
|
L5_1 = 153,
|
||||||
|
L5_2 = 156,
|
||||||
|
L6_0 = 180,
|
||||||
|
L6_1 = 183,
|
||||||
|
L6_2 = 186,
|
||||||
|
UNKNOWN = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern std::map<profile, std::string> profiles;
|
||||||
|
|
||||||
|
extern std::map<tier, std::string> profile_tiers;
|
||||||
|
|
||||||
|
extern std::map<level, std::string> levels;
|
||||||
|
|
||||||
|
} // namespace hevc
|
||||||
|
} // namespace codecs
|
||||||
|
} // namespace obsffmpeg
|
||||||
+16
-12
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2018 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#include "encoder.hpp"
|
#include "encoder.hpp"
|
||||||
|
|
||||||
|
|||||||
+17
-13
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2018 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#ifndef OBS_FFMPEG_ENCODER_HPP
|
#ifndef OBS_FFMPEG_ENCODER_HPP
|
||||||
#define OBS_FFMPEG_ENCODER_HPP
|
#define OBS_FFMPEG_ENCODER_HPP
|
||||||
@@ -124,7 +128,7 @@ namespace obsffmpeg {
|
|||||||
{ \
|
{ \
|
||||||
_source##_info.id = "obs-ffmpeg-encoder-" #_source; \
|
_source##_info.id = "obs-ffmpeg-encoder-" #_source; \
|
||||||
_source##_info.type = OBS_ENCODER_VIDEO; \
|
_source##_info.type = OBS_ENCODER_VIDEO; \
|
||||||
_source##_info.caps = 0; \
|
_source##_info.caps = OBS_ENCODER_CAP_DEPRECATED; \
|
||||||
_source##_info.codec = _codec; \
|
_source##_info.codec = _codec; \
|
||||||
_source##_info.create = _source##_create; \
|
_source##_info.create = _source##_create; \
|
||||||
_source##_info.destroy = _source##_destroy; \
|
_source##_info.destroy = _source##_destroy; \
|
||||||
|
|||||||
+164
-53
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2019 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#include "generic.hpp"
|
#include "generic.hpp"
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
@@ -28,9 +32,10 @@ extern "C" {
|
|||||||
#include <obs-module.h>
|
#include <obs-module.h>
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4244)
|
#pragma warning(disable : 4244)
|
||||||
#include "libavutil/dict.h"
|
#include <libavutil/dict.h>
|
||||||
#include "libavutil/frame.h"
|
#include <libavutil/frame.h>
|
||||||
#include "libavutil/opt.h"
|
#include <libavutil/opt.h>
|
||||||
|
#include <libavutil/pixdesc.h>
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,11 +69,11 @@ void encoder::generic_factory::register_encoder()
|
|||||||
// TODO: Figure out a way to translate from names to other names.
|
// TODO: Figure out a way to translate from names to other names.
|
||||||
{
|
{
|
||||||
std::stringstream sstr;
|
std::stringstream sstr;
|
||||||
sstr << "[FFmpeg] " << (avcodec_ptr->long_name ? avcodec_ptr->long_name : avcodec_ptr->name) << " ("
|
sstr << (avcodec_ptr->long_name ? avcodec_ptr->long_name : avcodec_ptr->name) << " ("
|
||||||
<< avcodec_ptr->name << ")";
|
<< avcodec_ptr->name << ")";
|
||||||
std::string caps = ffmpeg::tools::translate_encoder_capabilities(avcodec_ptr->capabilities);
|
std::string caps = ffmpeg::tools::translate_encoder_capabilities(avcodec_ptr->capabilities);
|
||||||
if (caps.length() != 0) {
|
if (caps.length() != 0) {
|
||||||
sstr << " (" << caps << ")";
|
sstr << " [" << caps << "]";
|
||||||
}
|
}
|
||||||
this->info.readable_name = sstr.str();
|
this->info.readable_name = sstr.str();
|
||||||
}
|
}
|
||||||
@@ -85,6 +90,13 @@ void encoder::generic_factory::register_encoder()
|
|||||||
this->info.oei.id = this->info.uid.c_str();
|
this->info.oei.id = this->info.uid.c_str();
|
||||||
this->info.oei.codec = this->info.codec.c_str();
|
this->info.oei.codec = this->info.codec.c_str();
|
||||||
|
|
||||||
|
// Is this a deprecated encoder?
|
||||||
|
#ifndef _DEBUG
|
||||||
|
if (!obsffmpeg::has_codec_handler(avcodec_ptr->name)) {
|
||||||
|
this->info.oei.caps |= OBS_ENCODER_CAP_DEPRECATED;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Detect encoder type (only Video and Audio supported)
|
// Detect encoder type (only Video and Audio supported)
|
||||||
if (avcodec_ptr->type == AVMediaType::AVMEDIA_TYPE_VIDEO) {
|
if (avcodec_ptr->type == AVMediaType::AVMEDIA_TYPE_VIDEO) {
|
||||||
this->info.oei.type = obs_encoder_type::OBS_ENCODER_VIDEO;
|
this->info.oei.type = obs_encoder_type::OBS_ENCODER_VIDEO;
|
||||||
@@ -271,7 +283,7 @@ void encoder::generic_factory::register_encoder()
|
|||||||
this->info.oei.type_data = this;
|
this->info.oei.type_data = this;
|
||||||
|
|
||||||
obs_register_encoder(&this->info.oei);
|
obs_register_encoder(&this->info.oei);
|
||||||
PLOG_INFO("Registered encoder #%llX with name '%s' and long name '%s' and caps %llX", avcodec_ptr,
|
PLOG_DEBUG("Registered encoder #%llX with name '%s' and long name '%s' and caps %llX", avcodec_ptr,
|
||||||
avcodec_ptr->name, avcodec_ptr->long_name, avcodec_ptr->capabilities);
|
avcodec_ptr->name, avcodec_ptr->long_name, avcodec_ptr->capabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,15 +320,20 @@ void encoder::generic_factory::get_properties(obs_properties_t* props)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
obs_properties_t* grp = props;
|
||||||
|
if (!obsffmpeg::are_property_groups_broken()) {
|
||||||
auto prs = obs_properties_create();
|
auto prs = obs_properties_create();
|
||||||
|
obs_properties_add_group(props, P_FFMPEG, TRANSLATE(P_FFMPEG), OBS_GROUP_NORMAL, prs);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto p =
|
auto p =
|
||||||
obs_properties_add_text(prs, P_FFMPEG_CUSTOMSETTINGS, TRANSLATE(P_FFMPEG_CUSTOMSETTINGS),
|
obs_properties_add_text(grp, P_FFMPEG_CUSTOMSETTINGS, TRANSLATE(P_FFMPEG_CUSTOMSETTINGS),
|
||||||
obs_text_type::OBS_TEXT_DEFAULT);
|
obs_text_type::OBS_TEXT_DEFAULT);
|
||||||
obs_property_set_long_description(p, TRANSLATE(DESC(P_FFMPEG_CUSTOMSETTINGS)));
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_FFMPEG_CUSTOMSETTINGS)));
|
||||||
}
|
}
|
||||||
if (this->avcodec_ptr->pix_fmts) {
|
if (this->avcodec_ptr->pix_fmts) {
|
||||||
auto p = obs_properties_add_list(prs, P_FFMPEG_COLORFORMAT, TRANSLATE(P_FFMPEG_COLORFORMAT),
|
auto p = obs_properties_add_list(grp, P_FFMPEG_COLORFORMAT, TRANSLATE(P_FFMPEG_COLORFORMAT),
|
||||||
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
||||||
obs_property_set_long_description(p, TRANSLATE(DESC(P_FFMPEG_COLORFORMAT)));
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_FFMPEG_COLORFORMAT)));
|
||||||
obs_property_list_add_int(p, TRANSLATE(P_AUTOMATIC), static_cast<int64_t>(AV_PIX_FMT_NONE));
|
obs_property_list_add_int(p, TRANSLATE(P_AUTOMATIC), static_cast<int64_t>(AV_PIX_FMT_NONE));
|
||||||
@@ -325,13 +342,13 @@ void encoder::generic_factory::get_properties(obs_properties_t* props)
|
|||||||
static_cast<int64_t>(*ptr));
|
static_cast<int64_t>(*ptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
if (this->avcodec_ptr->capabilities & (AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS)) {
|
||||||
auto p = obs_properties_add_int_slider(prs, P_FFMPEG_THREADS, TRANSLATE(P_FFMPEG_THREADS), 0,
|
auto p = obs_properties_add_int_slider(grp, P_FFMPEG_THREADS, TRANSLATE(P_FFMPEG_THREADS), 0,
|
||||||
std::thread::hardware_concurrency() * 2, 1);
|
std::thread::hardware_concurrency() * 2, 1);
|
||||||
obs_property_set_long_description(p, TRANSLATE(DESC(P_FFMPEG_THREADS)));
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_FFMPEG_THREADS)));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto p = obs_properties_add_list(prs, P_FFMPEG_STANDARDCOMPLIANCE,
|
auto p = obs_properties_add_list(grp, P_FFMPEG_STANDARDCOMPLIANCE,
|
||||||
TRANSLATE(P_FFMPEG_STANDARDCOMPLIANCE), OBS_COMBO_TYPE_LIST,
|
TRANSLATE(P_FFMPEG_STANDARDCOMPLIANCE), OBS_COMBO_TYPE_LIST,
|
||||||
OBS_COMBO_FORMAT_INT);
|
OBS_COMBO_FORMAT_INT);
|
||||||
obs_property_set_long_description(p, TRANSLATE(DESC(P_FFMPEG_STANDARDCOMPLIANCE)));
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_FFMPEG_STANDARDCOMPLIANCE)));
|
||||||
@@ -346,7 +363,6 @@ void encoder::generic_factory::get_properties(obs_properties_t* props)
|
|||||||
obs_property_list_add_int(p, TRANSLATE(P_FFMPEG_STANDARDCOMPLIANCE ".Experimental"),
|
obs_property_list_add_int(p, TRANSLATE(P_FFMPEG_STANDARDCOMPLIANCE ".Experimental"),
|
||||||
FF_COMPLIANCE_EXPERIMENTAL);
|
FF_COMPLIANCE_EXPERIMENTAL);
|
||||||
}
|
}
|
||||||
obs_properties_add_group(props, P_FFMPEG, TRANSLATE(P_FFMPEG), OBS_GROUP_NORMAL, prs);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,12 +396,13 @@ encoder::generic::generic(obs_data_t* settings, obs_encoder_t* encoder)
|
|||||||
static_cast<int>(obs_data_get_int(settings, P_FFMPEG_STANDARDCOMPLIANCE));
|
static_cast<int>(obs_data_get_int(settings, P_FFMPEG_STANDARDCOMPLIANCE));
|
||||||
this->context->debug = 0;
|
this->context->debug = 0;
|
||||||
/// Threading
|
/// Threading
|
||||||
|
if (this->codec->capabilities
|
||||||
|
& (AV_CODEC_CAP_AUTO_THREADS | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS)) {
|
||||||
|
if (this->codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) {
|
||||||
|
this->context->thread_type |= FF_THREAD_FRAME;
|
||||||
|
}
|
||||||
if (this->codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) {
|
if (this->codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) {
|
||||||
this->context->thread_type = FF_THREAD_SLICE;
|
this->context->thread_type |= FF_THREAD_SLICE;
|
||||||
} else if (this->codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) {
|
|
||||||
this->context->thread_type = FF_THREAD_FRAME;
|
|
||||||
} else {
|
|
||||||
this->context->thread_type = 0;
|
|
||||||
}
|
}
|
||||||
int64_t threads = obs_data_get_int(settings, P_FFMPEG_THREADS);
|
int64_t threads = obs_data_get_int(settings, P_FFMPEG_THREADS);
|
||||||
if (threads > 0) {
|
if (threads > 0) {
|
||||||
@@ -395,6 +412,7 @@ encoder::generic::generic(obs_data_t* settings, obs_encoder_t* encoder)
|
|||||||
this->context->thread_count = std::thread::hardware_concurrency();
|
this->context->thread_count = std::thread::hardware_concurrency();
|
||||||
this->lag_in_frames = this->context->thread_count;
|
this->lag_in_frames = this->context->thread_count;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Video and Audio exclusive setup
|
// Video and Audio exclusive setup
|
||||||
if (this->codec->type == AVMEDIA_TYPE_VIDEO) {
|
if (this->codec->type == AVMEDIA_TYPE_VIDEO) {
|
||||||
@@ -424,8 +442,51 @@ encoder::generic::generic(obs_data_t* settings, obs_encoder_t* encoder)
|
|||||||
AVPixelFormat source = ffmpeg::tools::obs_videoformat_to_avpixelformat(voi->format);
|
AVPixelFormat source = ffmpeg::tools::obs_videoformat_to_avpixelformat(voi->format);
|
||||||
AVPixelFormat target = AV_PIX_FMT_NONE;
|
AVPixelFormat target = AV_PIX_FMT_NONE;
|
||||||
|
|
||||||
|
// Prefer lossless or zero-change formats.
|
||||||
|
for (auto ptr = this->codec->pix_fmts; *ptr != AV_PIX_FMT_NONE; ptr++) {
|
||||||
|
switch (source) {
|
||||||
|
case AV_PIX_FMT_RGBA:
|
||||||
|
switch (*ptr) {
|
||||||
|
case AV_PIX_FMT_RGB0:
|
||||||
|
case AV_PIX_FMT_RGBA:
|
||||||
|
target = *ptr;
|
||||||
|
break;
|
||||||
|
case AV_PIX_FMT_BGR0:
|
||||||
|
case AV_PIX_FMT_BGRA:
|
||||||
|
target = *ptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AV_PIX_FMT_BGRA:
|
||||||
|
case AV_PIX_FMT_BGR0:
|
||||||
|
switch (*ptr) {
|
||||||
|
case AV_PIX_FMT_RGB0:
|
||||||
|
case AV_PIX_FMT_RGBA:
|
||||||
|
target = *ptr;
|
||||||
|
break;
|
||||||
|
case AV_PIX_FMT_BGR0:
|
||||||
|
case AV_PIX_FMT_BGRA:
|
||||||
|
target = *ptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AV_PIX_FMT_YUV444P:
|
||||||
|
case AV_PIX_FMT_YUYV422:
|
||||||
|
case AV_PIX_FMT_YVYU422:
|
||||||
|
case AV_PIX_FMT_UYVY422:
|
||||||
|
case AV_PIX_FMT_YUV420P:
|
||||||
|
case AV_PIX_FMT_NV12:
|
||||||
|
if (*ptr == source) {
|
||||||
|
target = *ptr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == AV_PIX_FMT_NONE) {
|
||||||
int loss = 0;
|
int loss = 0;
|
||||||
target = avcodec_find_best_pix_fmt_of_list(this->codec->pix_fmts, source, false, &loss);
|
target = avcodec_find_best_pix_fmt_of_list(this->codec->pix_fmts, source, false, &loss);
|
||||||
|
}
|
||||||
|
|
||||||
this->context->pix_fmt = target;
|
this->context->pix_fmt = target;
|
||||||
this->swscale.set_source_format(source);
|
this->swscale.set_source_format(source);
|
||||||
@@ -446,8 +507,8 @@ encoder::generic::generic(obs_data_t* settings, obs_encoder_t* encoder)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Framerate
|
// Framerate
|
||||||
this->context->time_base.num = voi->fps_num;
|
this->context->time_base.num = voi->fps_den;
|
||||||
this->context->time_base.den = voi->fps_den;
|
this->context->time_base.den = voi->fps_num;
|
||||||
this->context->ticks_per_frame = 1;
|
this->context->ticks_per_frame = 1;
|
||||||
} else if (this->codec->type == AVMEDIA_TYPE_AUDIO) {
|
} else if (this->codec->type == AVMEDIA_TYPE_AUDIO) {
|
||||||
}
|
}
|
||||||
@@ -479,20 +540,18 @@ encoder::generic::generic(obs_data_t* settings, obs_encoder_t* encoder)
|
|||||||
// Create Frame queue
|
// Create Frame queue
|
||||||
this->frame_queue.set_pixel_format(this->context->pix_fmt);
|
this->frame_queue.set_pixel_format(this->context->pix_fmt);
|
||||||
this->frame_queue.set_resolution(this->context->width, this->context->height);
|
this->frame_queue.set_resolution(this->context->width, this->context->height);
|
||||||
this->frame_queue.precache(std::thread::hardware_concurrency() / 4);
|
this->frame_queue.precache(2);
|
||||||
} else if (this->codec->type == AVMEDIA_TYPE_AUDIO) {
|
} else if (this->codec->type == AVMEDIA_TYPE_AUDIO) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create Packet
|
av_init_packet(&this->current_packet);
|
||||||
this->current_packet = av_packet_alloc();
|
av_new_packet(&this->current_packet, 8 * 1024 * 1024); // 8 MB precached Packet size.
|
||||||
if (!this->current_packet) {
|
|
||||||
PLOG_ERROR("Failed to allocate packet storage.");
|
|
||||||
throw std::runtime_error("Failed to allocate packet storage.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
encoder::generic::~generic()
|
encoder::generic::~generic()
|
||||||
{
|
{
|
||||||
|
av_packet_unref(&this->current_packet);
|
||||||
|
|
||||||
this->frame_queue.clear();
|
this->frame_queue.clear();
|
||||||
this->frame_queue_used.clear();
|
this->frame_queue_used.clear();
|
||||||
this->swscale.finalize();
|
this->swscale.finalize();
|
||||||
@@ -528,8 +587,8 @@ bool encoder::generic::update(obs_data_t* settings)
|
|||||||
|
|
||||||
{ // FFmpeg
|
{ // FFmpeg
|
||||||
// Apply custom options.
|
// Apply custom options.
|
||||||
av_opt_set_from_string(this->context, obs_data_get_string(settings, P_FFMPEG_CUSTOMSETTINGS), nullptr,
|
av_opt_set_from_string(this->context->priv_data, obs_data_get_string(settings, P_FFMPEG_CUSTOMSETTINGS),
|
||||||
";", "=");
|
nullptr, "=", ";");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -563,29 +622,72 @@ bool encoder::generic::get_extra_data(uint8_t** extra_data, size_t* size)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void copy_data(encoder_frame* frame, AVFrame* vframe)
|
||||||
|
{
|
||||||
|
int h_chroma_shift, v_chroma_shift;
|
||||||
|
av_pix_fmt_get_chroma_sub_sample(static_cast<AVPixelFormat>(vframe->format), &h_chroma_shift, &v_chroma_shift);
|
||||||
|
|
||||||
|
for (size_t idx = 0; idx < MAX_AV_PLANES; idx++) {
|
||||||
|
if (!frame->data[idx] || !vframe->data[idx])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
size_t plane_height = vframe->height >> (idx ? v_chroma_shift : 0);
|
||||||
|
|
||||||
|
if (static_cast<uint32_t>(vframe->linesize[idx]) == frame->linesize[idx]) {
|
||||||
|
std::memcpy(vframe->data[idx], frame->data[idx], frame->linesize[idx] * plane_height);
|
||||||
|
} else {
|
||||||
|
size_t ls_in = frame->linesize[idx];
|
||||||
|
size_t ls_out = vframe->linesize[idx];
|
||||||
|
size_t bytes = ls_in < ls_out ? ls_in : ls_out;
|
||||||
|
|
||||||
|
uint8_t* to = vframe->data[idx];
|
||||||
|
uint8_t* from = frame->data[idx];
|
||||||
|
|
||||||
|
for (size_t y = 0; y < plane_height; y++) {
|
||||||
|
std::memcpy(to, from, bytes);
|
||||||
|
to += ls_out;
|
||||||
|
from += ls_in;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool encoder::generic::video_encode(encoder_frame* frame, encoder_packet* packet, bool* received_packet)
|
bool encoder::generic::video_encode(encoder_frame* frame, encoder_packet* packet, bool* received_packet)
|
||||||
{
|
{
|
||||||
// Convert frame.
|
// Convert frame.
|
||||||
std::shared_ptr<AVFrame> vframe = frame_queue.pop(); // Retrieve an empty frame.
|
std::shared_ptr<AVFrame> vframe = frame_queue.pop(); // Retrieve an empty frame.
|
||||||
{
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
ScopeProfiler profile("convert");
|
ScopeProfiler profile("convert");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vframe->height = this->context->height;
|
||||||
|
vframe->format = this->context->pix_fmt;
|
||||||
vframe->color_range = this->context->color_range;
|
vframe->color_range = this->context->color_range;
|
||||||
vframe->colorspace = this->context->colorspace;
|
vframe->colorspace = this->context->colorspace;
|
||||||
|
|
||||||
int res =
|
if ((swscale.is_source_full_range() == swscale.is_target_full_range())
|
||||||
swscale.convert(reinterpret_cast<uint8_t**>(frame->data), reinterpret_cast<int*>(frame->linesize),
|
&& (swscale.get_source_colorspace() == swscale.get_target_colorspace())
|
||||||
0, this->context->height, vframe->data, vframe->linesize);
|
&& (swscale.get_source_format() == swscale.get_target_format())) {
|
||||||
|
copy_data(frame, vframe.get());
|
||||||
|
} else {
|
||||||
|
int res = swscale.convert(reinterpret_cast<uint8_t**>(frame->data),
|
||||||
|
reinterpret_cast<int*>(frame->linesize), 0, this->context->height,
|
||||||
|
vframe->data, vframe->linesize);
|
||||||
if (res <= 0) {
|
if (res <= 0) {
|
||||||
PLOG_ERROR("Failed to convert frame: %s (%ld).", ffmpeg::tools::get_error_description(res),
|
PLOG_ERROR("Failed to convert frame: %s (%ld).",
|
||||||
res);
|
ffmpeg::tools::get_error_description(res), res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Send and receive frames.
|
// Send and receive frames.
|
||||||
{
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
ScopeProfiler profile("loop");
|
ScopeProfiler profile("loop");
|
||||||
|
#endif
|
||||||
|
|
||||||
bool sent_frame = false;
|
bool sent_frame = false;
|
||||||
bool recv_packet = false;
|
bool recv_packet = false;
|
||||||
bool should_lag = (lag_in_frames - frame_count) <= 0;
|
bool should_lag = (lag_in_frames - frame_count) <= 0;
|
||||||
@@ -598,7 +700,9 @@ bool encoder::generic::video_encode(encoder_frame* frame, encoder_packet* packet
|
|||||||
bool eagain_is_stupid = false;
|
bool eagain_is_stupid = false;
|
||||||
|
|
||||||
if (!sent_frame) {
|
if (!sent_frame) {
|
||||||
|
#ifdef _DEBUG
|
||||||
ScopeProfiler profile_inner("send");
|
ScopeProfiler profile_inner("send");
|
||||||
|
#endif
|
||||||
|
|
||||||
vframe->pts = frame->pts;
|
vframe->pts = frame->pts;
|
||||||
|
|
||||||
@@ -606,7 +710,7 @@ bool encoder::generic::video_encode(encoder_frame* frame, encoder_packet* packet
|
|||||||
switch (res) {
|
switch (res) {
|
||||||
case 0:
|
case 0:
|
||||||
sent_frame = true;
|
sent_frame = true;
|
||||||
frame_count++;
|
vframe = nullptr;
|
||||||
break;
|
break;
|
||||||
case AVERROR(EAGAIN):
|
case AVERROR(EAGAIN):
|
||||||
// This means we should call receive_packet again, but what do we do with that data?
|
// This means we should call receive_packet again, but what do we do with that data?
|
||||||
@@ -615,7 +719,6 @@ bool encoder::generic::video_encode(encoder_frame* frame, encoder_packet* packet
|
|||||||
PLOG_WARNING(
|
PLOG_WARNING(
|
||||||
"Skipped frame due to EAGAIN when a packet was already returned.");
|
"Skipped frame due to EAGAIN when a packet was already returned.");
|
||||||
sent_frame = true;
|
sent_frame = true;
|
||||||
frame_count++;
|
|
||||||
}
|
}
|
||||||
eagain_is_stupid = true;
|
eagain_is_stupid = true;
|
||||||
break;
|
break;
|
||||||
@@ -631,7 +734,9 @@ bool encoder::generic::video_encode(encoder_frame* frame, encoder_packet* packet
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!recv_packet) {
|
if (!recv_packet) {
|
||||||
|
#ifdef _DEBUG
|
||||||
ScopeProfiler profile_inner("recieve");
|
ScopeProfiler profile_inner("recieve");
|
||||||
|
#endif
|
||||||
|
|
||||||
int res = receive_packet(received_packet, packet);
|
int res = receive_packet(received_packet, packet);
|
||||||
switch (res) {
|
switch (res) {
|
||||||
@@ -664,6 +769,10 @@ bool encoder::generic::video_encode(encoder_frame* frame, encoder_packet* packet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vframe != nullptr) {
|
||||||
|
frame_queue.push(vframe);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -674,14 +783,14 @@ bool encoder::generic::video_encode_texture(uint32_t, int64_t, uint64_t, uint64_
|
|||||||
|
|
||||||
int encoder::generic::receive_packet(bool* received_packet, struct encoder_packet* packet)
|
int encoder::generic::receive_packet(bool* received_packet, struct encoder_packet* packet)
|
||||||
{
|
{
|
||||||
int res = avcodec_receive_packet(this->context, this->current_packet);
|
int res = avcodec_receive_packet(this->context, &this->current_packet);
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
packet->type = OBS_ENCODER_VIDEO;
|
packet->type = OBS_ENCODER_VIDEO;
|
||||||
packet->pts = this->current_packet->pts;
|
packet->pts = this->current_packet.pts;
|
||||||
packet->dts = this->current_packet->pts;
|
packet->dts = this->current_packet.dts;
|
||||||
packet->data = this->current_packet->data;
|
packet->data = this->current_packet.data;
|
||||||
packet->size = this->current_packet->size;
|
packet->size = this->current_packet.size;
|
||||||
packet->keyframe = !!(this->current_packet->flags & AV_PKT_FLAG_KEY);
|
packet->keyframe = !!(this->current_packet.flags & AV_PKT_FLAG_KEY);
|
||||||
packet->drop_priority = 0;
|
packet->drop_priority = 0;
|
||||||
*received_packet = true;
|
*received_packet = true;
|
||||||
|
|
||||||
@@ -690,6 +799,7 @@ int encoder::generic::receive_packet(bool* received_packet, struct encoder_packe
|
|||||||
frame_queue.push(uframe);
|
frame_queue.push(uframe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -698,6 +808,7 @@ int encoder::generic::send_frame(std::shared_ptr<AVFrame> frame)
|
|||||||
int res = avcodec_send_frame(this->context, frame.get());
|
int res = avcodec_send_frame(this->context, frame.get());
|
||||||
switch (res) {
|
switch (res) {
|
||||||
case 0:
|
case 0:
|
||||||
|
frame_queue_used.push(frame);
|
||||||
frame_count++;
|
frame_count++;
|
||||||
case AVERROR(EAGAIN):
|
case AVERROR(EAGAIN):
|
||||||
case AVERROR(EOF):
|
case AVERROR(EOF):
|
||||||
|
|||||||
+17
-13
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2019 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
@@ -63,7 +67,7 @@ namespace encoder {
|
|||||||
ffmpeg::avframe_queue frame_queue;
|
ffmpeg::avframe_queue frame_queue;
|
||||||
ffmpeg::avframe_queue frame_queue_used;
|
ffmpeg::avframe_queue frame_queue_used;
|
||||||
ffmpeg::swscale swscale;
|
ffmpeg::swscale swscale;
|
||||||
AVPacket* current_packet = nullptr;
|
AVPacket current_packet;
|
||||||
|
|
||||||
int64_t lag_in_frames;
|
int64_t lag_in_frames;
|
||||||
int64_t frame_count;
|
int64_t frame_count;
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2018 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#include "prores_aw.hpp"
|
#include "prores_aw.hpp"
|
||||||
#include <obs-module.h>
|
#include <obs-module.h>
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2018 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2018 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#include "avframe-queue.hpp"
|
#include "avframe-queue.hpp"
|
||||||
#include "tools.hpp"
|
#include "tools.hpp"
|
||||||
@@ -26,7 +30,7 @@ std::shared_ptr<AVFrame> ffmpeg::avframe_queue::create_frame()
|
|||||||
frame->height = this->resolution.second;
|
frame->height = this->resolution.second;
|
||||||
frame->format = this->format;
|
frame->format = this->format;
|
||||||
|
|
||||||
int res = av_frame_get_buffer(frame.get(), 0);
|
int res = av_frame_get_buffer(frame.get(), 32);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
throw std::exception(ffmpeg::tools::get_error_description(res));
|
throw std::exception(ffmpeg::tools::get_error_description(res));
|
||||||
}
|
}
|
||||||
@@ -105,7 +109,8 @@ std::shared_ptr<AVFrame> ffmpeg::avframe_queue::pop()
|
|||||||
ret = create_frame();
|
ret = create_frame();
|
||||||
} else {
|
} else {
|
||||||
frames.pop_front();
|
frames.pop_front();
|
||||||
if ((ret->width != this->resolution.first) || (ret->height != this->resolution.second)
|
if ((static_cast<uint32_t>(ret->width) != this->resolution.first)
|
||||||
|
|| (static_cast<uint32_t>(ret->height) != this->resolution.second)
|
||||||
|| (ret->format != this->format)) {
|
|| (ret->format != this->format)) {
|
||||||
ret = nullptr;
|
ret = nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2018 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|||||||
+16
-12
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2018 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#include "swscale.hpp"
|
#include "swscale.hpp"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|||||||
+16
-12
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2018 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#ifndef OBS_FFMPEG_FFMPEG_SWSCALE
|
#ifndef OBS_FFMPEG_FFMPEG_SWSCALE
|
||||||
#define OBS_FFMPEG_FFMPEG_SWSCALE
|
#define OBS_FFMPEG_FFMPEG_SWSCALE
|
||||||
|
|||||||
+22
-18
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2018 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#include "tools.hpp"
|
#include "tools.hpp"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -36,12 +40,12 @@ std::string ffmpeg::tools::translate_encoder_capabilities(int capabilities)
|
|||||||
|
|
||||||
// Quality
|
// Quality
|
||||||
{AV_CODEC_CAP_LOSSLESS, "Lossless"},
|
{AV_CODEC_CAP_LOSSLESS, "Lossless"},
|
||||||
{AV_CODEC_CAP_INTRA_ONLY, "I-Frames only"},
|
//{AV_CODEC_CAP_INTRA_ONLY, "I-Frames only"},
|
||||||
|
|
||||||
// Threading
|
// Threading
|
||||||
{AV_CODEC_CAP_FRAME_THREADS, "Frame-Threading"},
|
//{AV_CODEC_CAP_FRAME_THREADS, "Frame-Threading"},
|
||||||
{AV_CODEC_CAP_SLICE_THREADS, "Slice-Threading"},
|
//{AV_CODEC_CAP_SLICE_THREADS, "Slice-Threading"},
|
||||||
{AV_CODEC_CAP_AUTO_THREADS, "Automatic-Threading"},
|
//{AV_CODEC_CAP_AUTO_THREADS, "Automatic-Threading"},
|
||||||
|
|
||||||
// Features
|
// Features
|
||||||
{AV_CODEC_CAP_PARAM_CHANGE, "Dynamic Parameter Change"},
|
{AV_CODEC_CAP_PARAM_CHANGE, "Dynamic Parameter Change"},
|
||||||
@@ -49,7 +53,7 @@ std::string ffmpeg::tools::translate_encoder_capabilities(int capabilities)
|
|||||||
{AV_CODEC_CAP_VARIABLE_FRAME_SIZE, "Variable Frame Size"},
|
{AV_CODEC_CAP_VARIABLE_FRAME_SIZE, "Variable Frame Size"},
|
||||||
{AV_CODEC_CAP_SMALL_LAST_FRAME, "Small Final Frame"},
|
{AV_CODEC_CAP_SMALL_LAST_FRAME, "Small Final Frame"},
|
||||||
//{AV_CODEC_CAP_DR1, "Uses get_buffer"},
|
//{AV_CODEC_CAP_DR1, "Uses get_buffer"},
|
||||||
{AV_CODEC_CAP_DELAY, "Requires Flush"},
|
//{AV_CODEC_CAP_DELAY, "Requires Flush"},
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
{AV_CODEC_CAP_TRUNCATED, "Truncated"},
|
{AV_CODEC_CAP_TRUNCATED, "Truncated"},
|
||||||
@@ -169,7 +173,7 @@ AVPixelFormat ffmpeg::tools::obs_videoformat_to_avpixelformat(video_format v)
|
|||||||
switch (v) {
|
switch (v) {
|
||||||
// 32-Bits
|
// 32-Bits
|
||||||
case VIDEO_FORMAT_BGRX:
|
case VIDEO_FORMAT_BGRX:
|
||||||
return AV_PIX_FMT_BGRA;
|
return AV_PIX_FMT_BGR0;
|
||||||
case VIDEO_FORMAT_BGRA:
|
case VIDEO_FORMAT_BGRA:
|
||||||
return AV_PIX_FMT_BGRA;
|
return AV_PIX_FMT_BGRA;
|
||||||
case VIDEO_FORMAT_RGBA:
|
case VIDEO_FORMAT_RGBA:
|
||||||
|
|||||||
+16
-12
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2018 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#ifndef OBS_FFMPEG_FFMPEG_UTILITY
|
#ifndef OBS_FFMPEG_FFMPEG_UTILITY
|
||||||
#define OBS_FFMPEG_FFMPEG_UTILITY
|
#define OBS_FFMPEG_FFMPEG_UTILITY
|
||||||
|
|||||||
+22
-12
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2018 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#include "plugin.hpp"
|
#include "plugin.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -54,6 +58,12 @@ std::shared_ptr<obsffmpeg::ui::handler> obsffmpeg::find_codec_handler(std::strin
|
|||||||
return found->second;
|
return found->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool obsffmpeg::has_codec_handler(std::string codec)
|
||||||
|
{
|
||||||
|
auto found = codec_to_handler_map.find(codec);
|
||||||
|
return (found != codec_to_handler_map.end());
|
||||||
|
}
|
||||||
|
|
||||||
static std::map<AVCodec*, std::shared_ptr<encoder::generic_factory>> generic_factories;
|
static std::map<AVCodec*, std::shared_ptr<encoder::generic_factory>> generic_factories;
|
||||||
|
|
||||||
MODULE_EXPORT bool obs_module_load(void)
|
MODULE_EXPORT bool obs_module_load(void)
|
||||||
|
|||||||
+18
-12
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2019 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@@ -31,6 +35,8 @@ namespace obsffmpeg {
|
|||||||
|
|
||||||
std::shared_ptr<obsffmpeg::ui::handler> find_codec_handler(std::string codec);
|
std::shared_ptr<obsffmpeg::ui::handler> find_codec_handler(std::string codec);
|
||||||
|
|
||||||
|
bool has_codec_handler(std::string codec);
|
||||||
|
|
||||||
} // namespace obsffmpeg
|
} // namespace obsffmpeg
|
||||||
|
|
||||||
MODULE_EXPORT bool obs_module_load(void);
|
MODULE_EXPORT bool obs_module_load(void);
|
||||||
|
|||||||
+45
-19
@@ -1,27 +1,53 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2019 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
#define P_RATECONTROL "RateControl"
|
#define G_STATE_DEFAULT "State.Default"
|
||||||
#define P_RATECONTROL_METHOD "RateControl.Method"
|
#define G_STATE_DISABLED "State.Disabled"
|
||||||
#define P_RATECONTROL_METHOD_(x) "RateControl.Method." D_VSTR(x)
|
#define G_STATE_ENABLED "State.Enabled"
|
||||||
#define P_RATECONTROL_BITRATE_TARGET "RateControl.Bitrate.Target"
|
#define G_STATE_AUTOMATIC "State.Automatic"
|
||||||
#define P_RATECONTROL_BITRATE_MINIMUM "RateControl.Bitrate.Minimum"
|
#define G_STATE_MANUAL "State.Manual"
|
||||||
#define P_RATECONTROL_BITRATE_MAXIMUM "RateControl.Bitrate.Maximum"
|
|
||||||
#define P_RATECONTROL_BUFFERSIZE "RateControl.BufferSize"
|
#define G_RATECONTROL "RateControl"
|
||||||
|
#define G_RATECONTROL_MODE "RateControl.Mode"
|
||||||
|
#define G_RATECONTROL_MODE_(x) "RateControl.Mode." D_VSTR(x)
|
||||||
|
#define G_RATECONTROL_BITRATE_TARGET "RateControl.Bitrate.Target"
|
||||||
|
#define G_RATECONTROL_BITRATE_MINIMUM "RateControl.Bitrate.Minimum"
|
||||||
|
#define G_RATECONTROL_BITRATE_MAXIMUM "RateControl.Bitrate.Maximum"
|
||||||
|
#define G_RATECONTROL_BUFFERSIZE "RateControl.BufferSize"
|
||||||
|
#define G_RATECONTROL_QUALITY_TARGET "RateControl.Quality.Target"
|
||||||
|
#define G_RATECONTROL_QUALITY_MINIMUM "RateControl.Quality.Minimum"
|
||||||
|
#define G_RATECONTROL_QUALITY_MAXIMUM "RateControl.Quality.Maximum"
|
||||||
|
#define G_RATECONTROL_QP_I "RateControl.QP.I"
|
||||||
|
#define G_RATECONTROL_QP_P "RateControl.QP.P"
|
||||||
|
#define G_RATECONTROL_QP_B "RateControl.QP.B"
|
||||||
|
#define G_RATECONTROL_QP_I_INITIAL "RateControl.QP.I.Initial"
|
||||||
|
#define G_RATECONTROL_QP_P_INITIAL "RateControl.QP.P.Initial"
|
||||||
|
#define G_RATECONTROL_QP_B_INITIAL "RateControl.QP.B.Initial"
|
||||||
|
|
||||||
|
#define G_KEYFRAMES "KeyFrames"
|
||||||
|
#define G_KEYFRAMES_INTERVALTYPE "KeyFrames.IntervalType"
|
||||||
|
#define G_KEYFRAMES_INTERVALTYPE_(x) "KeyFrames.IntervalType." D_VSTR(x)
|
||||||
|
#define G_KEYFRAMES_INTERVAL "KeyFrames.Interval"
|
||||||
|
#define G_KEYFRAMES_INTERVAL_SECONDS "KeyFrames.Interval.Seconds"
|
||||||
|
#define G_KEYFRAMES_INTERVAL_FRAMES "KeyFrames.Interval.Frames"
|
||||||
|
|||||||
+22
-16
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2019 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#include "debug_handler.hpp"
|
#include "debug_handler.hpp"
|
||||||
#include <map>
|
#include <map>
|
||||||
@@ -31,7 +35,7 @@ extern "C" {
|
|||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
}
|
}
|
||||||
|
|
||||||
void obsffmpeg::ui::debug_handler::get_defaults(obs_data_t* settings, AVCodec* codec, AVCodecContext* context) {}
|
void obsffmpeg::ui::debug_handler::get_defaults(obs_data_t*, AVCodec*, AVCodecContext*) {}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::string to_string(T value){};
|
std::string to_string(T value){};
|
||||||
@@ -60,14 +64,16 @@ std::string to_string(double_t value)
|
|||||||
return std::string(buf.data(), buf.data() + buf.size());
|
return std::string(buf.data(), buf.data() + buf.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void obsffmpeg::ui::debug_handler::get_properties(obs_properties_t* props, AVCodec* codec, AVCodecContext* context)
|
void obsffmpeg::ui::debug_handler::get_properties(obs_properties_t*, AVCodec* codec, AVCodecContext* context)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
AVCodecContext* ctx = avcodec_alloc_context3(codec);
|
AVCodecContext* ctx = avcodec_alloc_context3(codec);
|
||||||
if (!ctx->priv_data)
|
if (!ctx->priv_data) {
|
||||||
|
avcodec_free_context(&ctx);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PLOG_INFO("Options for '%s':", codec->name);
|
PLOG_INFO("Options for '%s':", codec->name);
|
||||||
|
|
||||||
@@ -200,4 +206,4 @@ void obsffmpeg::ui::debug_handler::get_properties(obs_properties_t* props, AVCod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void obsffmpeg::ui::debug_handler::update(obs_data_t* settings, AVCodec* codec, AVCodecContext* context) {}
|
void obsffmpeg::ui::debug_handler::update(obs_data_t*, AVCodec*, AVCodecContext*) {}
|
||||||
|
|||||||
+16
-12
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2019 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "handler.hpp"
|
#include "handler.hpp"
|
||||||
|
|||||||
+16
-12
@@ -1,18 +1,22 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2019 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#include "handler.hpp"
|
#include "handler.hpp"
|
||||||
|
|||||||
+16
-12
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2019 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,162 @@
|
|||||||
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#include "nvenc_h264_handler.hpp"
|
||||||
|
#include "codecs/h264.hpp"
|
||||||
|
#include "nvenc_shared.hpp"
|
||||||
|
#include "plugin.hpp"
|
||||||
|
#include "strings.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <obs-module.h>
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4244)
|
||||||
|
#include <libavutil/opt.h>
|
||||||
|
#pragma warning(pop)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Missing Options:
|
||||||
|
|
||||||
|
Seem to be covered by initQP_* instead.
|
||||||
|
- [obs-ffmpeg-encoder] Option 'cq' with help 'Set target quality level (0 to 51, 0 means automatic) for constant quality mode in VBR rate control' of type 'Float' with default value '0.000000', minimum '0.000000' and maximum '51.000000'.
|
||||||
|
- [obs-ffmpeg-encoder] Option 'qp' with help 'Constant quantization parameter rate control method' of type 'Int' with default value '-1', minimum '-1.000000' and maximum '51.000000'.
|
||||||
|
|
||||||
|
Not sure what there are useful for.
|
||||||
|
[obs-ffmpeg-encoder] Option 'aud' with help 'Use access unit delimiters' of type 'Bool' with default value 'false', minimum '0.000000' and maximum '1.000000'.
|
||||||
|
[obs-ffmpeg-encoder] Option 'surfaces' with help 'Number of concurrent surfaces' of type 'Int' with default value '0', minimum '0.000000' and maximum '64.000000'.
|
||||||
|
[obs-ffmpeg-encoder] Option 'delay' with help 'Delay frame output by the given amount of frames' of type 'Int' with default value '2147483647', minimum '0.000000' and maximum '2147483647.000000'.
|
||||||
|
|
||||||
|
Should probably add this.
|
||||||
|
[obs-ffmpeg-encoder] Option 'gpu' with unit (gpu) with help 'Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on.' of type 'Int' with default value '-1', minimum '-2.000000' and maximum '2147483647.000000'.
|
||||||
|
[obs-ffmpeg-encoder] [gpu] Constant 'any' and help text 'Pick the first device available' with value '-1'.
|
||||||
|
[obs-ffmpeg-encoder] [gpu] Constant 'list' and help text 'List the available devices' with value '-2'.
|
||||||
|
|
||||||
|
Useless except for strict_gop maybe?
|
||||||
|
[obs-ffmpeg-encoder] Option 'forced-idr' with help 'If forcing keyframes, force them as IDR frames.' of type 'Bool' with default value 'false', minimum '-1.000000' and maximum '1.000000'.
|
||||||
|
[obs-ffmpeg-encoder] Option 'strict_gop' with help 'Set 1 to minimize GOP-to-GOP rate fluctuations' of type 'Bool' with default value 'false', minimum '0.000000' and maximum '1.000000'.
|
||||||
|
[obs-ffmpeg-encoder] Option 'bluray-compat' with help 'Bluray compatibility workarounds' of type 'Bool' with default value 'false', minimum '0.000000' and maximum '1.000000'.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using namespace obsffmpeg::codecs::h264;
|
||||||
|
|
||||||
|
std::map<profile, std::string> profiles{
|
||||||
|
{profile::BASELINE, "baseline"},
|
||||||
|
{profile::MAIN, "main"},
|
||||||
|
{profile::HIGH, "high"},
|
||||||
|
{profile::HIGH444_PREDICTIVE, "high444p"},
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<level, std::string> levels{
|
||||||
|
{level::L1_0, "1.0"}, {level::L1_0b, "1.0b"}, {level::L1_1, "1.1"}, {level::L1_2, "1.2"}, {level::L1_3, "1.3"},
|
||||||
|
{level::L2_0, "2.0"}, {level::L2_1, "2.1"}, {level::L2_2, "2.2"}, {level::L3_0, "3.0"}, {level::L3_1, "3.1"},
|
||||||
|
{level::L3_2, "3.2"}, {level::L4_0, "4.0"}, {level::L4_1, "4.1"}, {level::L4_2, "4.2"}, {level::L5_0, "5.0"},
|
||||||
|
{level::L5_1, "5.1"}, {level::L5_2, "5.2"},
|
||||||
|
};
|
||||||
|
|
||||||
|
INITIALIZER(nvenc_h264_handler_init)
|
||||||
|
{
|
||||||
|
obsffmpeg::initializers.push_back([]() {
|
||||||
|
obsffmpeg::register_codec_handler("h264_nvenc", std::make_shared<obsffmpeg::ui::nvenc_h264_handler>());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
void obsffmpeg::ui::nvenc_h264_handler::get_defaults(obs_data_t* settings, AVCodec* codec, AVCodecContext* context)
|
||||||
|
{
|
||||||
|
nvenc::get_defaults(settings, codec, context);
|
||||||
|
|
||||||
|
obs_data_set_default_int(settings, P_H264_PROFILE, static_cast<int64_t>(codecs::h264::profile::HIGH));
|
||||||
|
obs_data_set_default_int(settings, P_H264_LEVEL, static_cast<int64_t>(codecs::h264::level::UNKNOWN));
|
||||||
|
}
|
||||||
|
|
||||||
|
void obsffmpeg::ui::nvenc_h264_handler::get_properties(obs_properties_t* props, AVCodec* codec, AVCodecContext* context)
|
||||||
|
{
|
||||||
|
if (!context) {
|
||||||
|
this->get_encoder_properties(props, codec);
|
||||||
|
} else {
|
||||||
|
this->get_runtime_properties(props, codec, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void obsffmpeg::ui::nvenc_h264_handler::update(obs_data_t* settings, AVCodec* codec, AVCodecContext* context)
|
||||||
|
{
|
||||||
|
nvenc::update(settings, codec, context);
|
||||||
|
|
||||||
|
{
|
||||||
|
auto found =
|
||||||
|
profiles.find(static_cast<codecs::h264::profile>(obs_data_get_int(settings, P_H264_PROFILE)));
|
||||||
|
if (found != profiles.end()) {
|
||||||
|
av_opt_set(context->priv_data, "profile", found->second.c_str(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto found = levels.find(static_cast<codecs::h264::level>(obs_data_get_int(settings, P_H264_LEVEL)));
|
||||||
|
if (found != levels.end()) {
|
||||||
|
av_opt_set(context->priv_data, "level", found->second.c_str(), 0);
|
||||||
|
} else {
|
||||||
|
av_opt_set(context->priv_data, "level", "auto", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void obsffmpeg::ui::nvenc_h264_handler::get_encoder_properties(obs_properties_t* props, AVCodec* codec)
|
||||||
|
{
|
||||||
|
nvenc::get_properties_pre(props, codec);
|
||||||
|
|
||||||
|
{
|
||||||
|
obs_properties_t* grp = props;
|
||||||
|
if (!obsffmpeg::are_property_groups_broken()) {
|
||||||
|
grp = obs_properties_create();
|
||||||
|
obs_properties_add_group(props, P_H264, TRANSLATE(P_H264), OBS_GROUP_NORMAL, grp);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_list(grp, P_H264_PROFILE, TRANSLATE(P_H264_PROFILE),
|
||||||
|
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_H264_PROFILE)));
|
||||||
|
obs_property_list_add_int(p, TRANSLATE(G_STATE_DEFAULT),
|
||||||
|
static_cast<int64_t>(codecs::h264::profile::UNKNOWN));
|
||||||
|
for (auto kv : profiles) {
|
||||||
|
std::string trans = std::string(P_H264_PROFILE) + "." + kv.second;
|
||||||
|
obs_property_list_add_int(p, TRANSLATE(trans.c_str()), static_cast<int64_t>(kv.first));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_list(grp, P_H264_LEVEL, TRANSLATE(P_H264_LEVEL),
|
||||||
|
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_H264_LEVEL)));
|
||||||
|
obs_property_list_add_int(p, TRANSLATE(G_STATE_AUTOMATIC),
|
||||||
|
static_cast<int64_t>(codecs::h264::level::UNKNOWN));
|
||||||
|
for (auto kv : levels) {
|
||||||
|
obs_property_list_add_int(p, kv.second.c_str(), static_cast<int64_t>(kv.first));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nvenc::get_properties_post(props, codec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void obsffmpeg::ui::nvenc_h264_handler::get_runtime_properties(obs_properties_t* props, AVCodec* codec,
|
||||||
|
AVCodecContext* context)
|
||||||
|
{
|
||||||
|
nvenc::get_runtime_properties(props, codec, context);
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "handler.hpp"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <obs-properties.h>
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4244)
|
||||||
|
#include <libavcodec/avcodec.h>
|
||||||
|
#pragma warning(pop)
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace obsffmpeg {
|
||||||
|
namespace ui {
|
||||||
|
class nvenc_h264_handler : public handler {
|
||||||
|
public:
|
||||||
|
virtual void get_defaults(obs_data_t* settings, AVCodec* codec,
|
||||||
|
AVCodecContext* context) override;
|
||||||
|
|
||||||
|
virtual void get_properties(obs_properties_t* props, AVCodec* codec,
|
||||||
|
AVCodecContext* context) override;
|
||||||
|
|
||||||
|
virtual void update(obs_data_t* settings, AVCodec* codec, AVCodecContext* context) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void get_encoder_properties(obs_properties_t* props, AVCodec* codec);
|
||||||
|
|
||||||
|
void get_runtime_properties(obs_properties_t* props, AVCodec* codec, AVCodecContext* context);
|
||||||
|
};
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace obsffmpeg
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#include "nvenc_hevc_handler.hpp"
|
||||||
|
#include "codecs/hevc.hpp"
|
||||||
|
#include "nvenc_shared.hpp"
|
||||||
|
#include "plugin.hpp"
|
||||||
|
#include "strings.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <obs-module.h>
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4244)
|
||||||
|
#include <libavutil/opt.h>
|
||||||
|
#pragma warning(pop)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Missing Options:
|
||||||
|
|
||||||
|
Seem to be covered by initQP_* instead.
|
||||||
|
- [obs-ffmpeg-encoder] Option 'cq' with help 'Set target quality level (0 to 51, 0 means automatic) for constant quality mode in VBR rate control' of type 'Float' with default value '0.000000', minimum '0.000000' and maximum '51.000000'.
|
||||||
|
- [obs-ffmpeg-encoder] Option 'qp' with help 'Constant quantization parameter rate control method' of type 'Int' with default value '-1', minimum '-1.000000' and maximum '51.000000'.
|
||||||
|
|
||||||
|
Not sure what there are useful for.
|
||||||
|
[obs-ffmpeg-encoder] Option 'aud' with help 'Use access unit delimiters' of type 'Bool' with default value 'false', minimum '0.000000' and maximum '1.000000'.
|
||||||
|
[obs-ffmpeg-encoder] Option 'surfaces' with help 'Number of concurrent surfaces' of type 'Int' with default value '0', minimum '0.000000' and maximum '64.000000'.
|
||||||
|
[obs-ffmpeg-encoder] Option 'delay' with help 'Delay frame output by the given amount of frames' of type 'Int' with default value '2147483647', minimum '0.000000' and maximum '2147483647.000000'.
|
||||||
|
|
||||||
|
Should probably add this.
|
||||||
|
[obs-ffmpeg-encoder] Option 'gpu' with unit (gpu) with help 'Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on.' of type 'Int' with default value '-1', minimum '-2.000000' and maximum '2147483647.000000'.
|
||||||
|
[obs-ffmpeg-encoder] [gpu] Constant 'any' and help text 'Pick the first device available' with value '-1'.
|
||||||
|
[obs-ffmpeg-encoder] [gpu] Constant 'list' and help text 'List the available devices' with value '-2'.
|
||||||
|
|
||||||
|
Useless except for strict_gop maybe?
|
||||||
|
[obs-ffmpeg-encoder] Option 'forced-idr' with help 'If forcing keyframes, force them as IDR frames.' of type 'Bool' with default value 'false', minimum '-1.000000' and maximum '1.000000'.
|
||||||
|
[obs-ffmpeg-encoder] Option 'strict_gop' with help 'Set 1 to minimize GOP-to-GOP rate fluctuations' of type 'Bool' with default value 'false', minimum '0.000000' and maximum '1.000000'.
|
||||||
|
[obs-ffmpeg-encoder] Option 'bluray-compat' with help 'Bluray compatibility workarounds' of type 'Bool' with default value 'false', minimum '0.000000' and maximum '1.000000'.
|
||||||
|
*/
|
||||||
|
|
||||||
|
INITIALIZER(nvenc_hevc_handler_init)
|
||||||
|
{
|
||||||
|
obsffmpeg::initializers.push_back([]() {
|
||||||
|
obsffmpeg::register_codec_handler("hevc_nvenc", std::make_shared<obsffmpeg::ui::nvenc_hevc_handler>());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
void obsffmpeg::ui::nvenc_hevc_handler::get_defaults(obs_data_t* settings, AVCodec* codec, AVCodecContext* context)
|
||||||
|
{
|
||||||
|
nvenc::get_defaults(settings, codec, context);
|
||||||
|
|
||||||
|
obs_data_set_default_int(settings, P_HEVC_PROFILE, static_cast<int64_t>(codecs::hevc::profile::MAIN));
|
||||||
|
obs_data_set_default_int(settings, P_HEVC_TIER, static_cast<int64_t>(codecs::hevc::profile::MAIN));
|
||||||
|
obs_data_set_default_int(settings, P_HEVC_LEVEL, static_cast<int64_t>(codecs::hevc::level::UNKNOWN));
|
||||||
|
}
|
||||||
|
|
||||||
|
void obsffmpeg::ui::nvenc_hevc_handler::get_properties(obs_properties_t* props, AVCodec* codec, AVCodecContext* context)
|
||||||
|
{
|
||||||
|
if (!context) {
|
||||||
|
this->get_encoder_properties(props, codec);
|
||||||
|
} else {
|
||||||
|
this->get_runtime_properties(props, codec, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void obsffmpeg::ui::nvenc_hevc_handler::update(obs_data_t* settings, AVCodec* codec, AVCodecContext* context)
|
||||||
|
{
|
||||||
|
nvenc::update(settings, codec, context);
|
||||||
|
|
||||||
|
{ // HEVC Options
|
||||||
|
codecs::hevc::profile profile =
|
||||||
|
static_cast<codecs::hevc::profile>(obs_data_get_int(settings, P_HEVC_PROFILE));
|
||||||
|
switch (profile) {
|
||||||
|
case codecs::hevc::profile::MAIN:
|
||||||
|
case codecs::hevc::profile::MAIN10:
|
||||||
|
case codecs::hevc::profile::RANGE_EXTENDED:
|
||||||
|
av_opt_set_int(context->priv_data, "profile", static_cast<int64_t>(profile), 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
av_opt_set_int(context->priv_data, "profile", static_cast<int64_t>(codecs::hevc::profile::MAIN),
|
||||||
|
0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
codecs::hevc::tier tier = static_cast<codecs::hevc::tier>(obs_data_get_int(settings, P_HEVC_TIER));
|
||||||
|
switch (tier) {
|
||||||
|
case codecs::hevc::tier::MAIN:
|
||||||
|
case codecs::hevc::tier::HIGH:
|
||||||
|
av_opt_set_int(context->priv_data, "tier", static_cast<int64_t>(tier), 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
av_opt_set_int(context->priv_data, "tier", static_cast<int64_t>(codecs::hevc::tier::MAIN), 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
codecs::hevc::level level = static_cast<codecs::hevc::level>(obs_data_get_int(settings, P_HEVC_LEVEL));
|
||||||
|
if (level != codecs::hevc::level::UNKNOWN) {
|
||||||
|
av_opt_set_int(context->priv_data, "level", static_cast<int64_t>(level), 0);
|
||||||
|
} else {
|
||||||
|
av_opt_set_int(context->priv_data, "level", static_cast<int64_t>(0), 0); // Automatic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void obsffmpeg::ui::nvenc_hevc_handler::get_encoder_properties(obs_properties_t* props, AVCodec* codec)
|
||||||
|
{
|
||||||
|
nvenc::get_properties_pre(props, codec);
|
||||||
|
|
||||||
|
{
|
||||||
|
obs_properties_t* grp = props;
|
||||||
|
if (!obsffmpeg::are_property_groups_broken()) {
|
||||||
|
grp = obs_properties_create();
|
||||||
|
obs_properties_add_group(props, P_HEVC, TRANSLATE(P_HEVC), OBS_GROUP_NORMAL, grp);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_list(grp, P_HEVC_PROFILE, TRANSLATE(P_HEVC_PROFILE),
|
||||||
|
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_HEVC_PROFILE)));
|
||||||
|
obs_property_list_add_int(p, TRANSLATE(G_STATE_DEFAULT),
|
||||||
|
static_cast<int64_t>(codecs::hevc::profile::UNKNOWN));
|
||||||
|
for (auto kv : codecs::hevc::profiles) {
|
||||||
|
std::string trans = std::string(P_HEVC_PROFILE) + "." + kv.second;
|
||||||
|
obs_property_list_add_int(p, TRANSLATE(trans.c_str()), static_cast<int64_t>(kv.first));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_list(grp, P_HEVC_TIER, TRANSLATE(P_HEVC_TIER), OBS_COMBO_TYPE_LIST,
|
||||||
|
OBS_COMBO_FORMAT_INT);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_HEVC_TIER)));
|
||||||
|
obs_property_list_add_int(p, TRANSLATE(G_STATE_DEFAULT),
|
||||||
|
static_cast<int64_t>(codecs::hevc::tier::UNKNOWN));
|
||||||
|
for (auto kv : codecs::hevc::profile_tiers) {
|
||||||
|
std::string trans = std::string(P_HEVC_TIER) + "." + kv.second;
|
||||||
|
obs_property_list_add_int(p, TRANSLATE(trans.c_str()), static_cast<int64_t>(kv.first));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_list(grp, P_HEVC_LEVEL, TRANSLATE(P_HEVC_LEVEL),
|
||||||
|
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_HEVC_LEVEL)));
|
||||||
|
obs_property_list_add_int(p, TRANSLATE(G_STATE_AUTOMATIC),
|
||||||
|
static_cast<int64_t>(codecs::hevc::level::UNKNOWN));
|
||||||
|
for (auto kv : codecs::hevc::levels) {
|
||||||
|
obs_property_list_add_int(p, kv.second.c_str(), static_cast<int64_t>(kv.first));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nvenc::get_properties_post(props, codec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void obsffmpeg::ui::nvenc_hevc_handler::get_runtime_properties(obs_properties_t* props, AVCodec* codec,
|
||||||
|
AVCodecContext* context)
|
||||||
|
{
|
||||||
|
nvenc::get_runtime_properties(props, codec, context);
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "handler.hpp"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <obs-properties.h>
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4244)
|
||||||
|
#include <libavcodec/avcodec.h>
|
||||||
|
#pragma warning(pop)
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace obsffmpeg {
|
||||||
|
namespace ui {
|
||||||
|
class nvenc_hevc_handler : public handler {
|
||||||
|
public:
|
||||||
|
virtual void get_defaults(obs_data_t* settings, AVCodec* codec,
|
||||||
|
AVCodecContext* context) override;
|
||||||
|
|
||||||
|
virtual void get_properties(obs_properties_t* props, AVCodec* codec,
|
||||||
|
AVCodecContext* context) override;
|
||||||
|
|
||||||
|
virtual void update(obs_data_t* settings, AVCodec* codec, AVCodecContext* context) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void get_encoder_properties(obs_properties_t* props, AVCodec* codec);
|
||||||
|
|
||||||
|
void get_runtime_properties(obs_properties_t* props, AVCodec* codec, AVCodecContext* context);
|
||||||
|
};
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace obsffmpeg
|
||||||
@@ -0,0 +1,695 @@
|
|||||||
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#include "nvenc_shared.hpp"
|
||||||
|
#include "codecs/hevc.hpp"
|
||||||
|
#include "plugin.hpp"
|
||||||
|
#include "strings.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <obs-module.h>
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4244)
|
||||||
|
#include <libavutil/opt.h>
|
||||||
|
#pragma warning(pop)
|
||||||
|
}
|
||||||
|
|
||||||
|
#define P_PRESET "NVENC.Preset"
|
||||||
|
#define P_PRESET_(x) P_PRESET "." D_VSTR(x)
|
||||||
|
|
||||||
|
#define P_RATECONTROL "NVENC.RateControl"
|
||||||
|
#define P_RATECONTROL_MODE P_RATECONTROL ".Mode"
|
||||||
|
#define P_RATECONTROL_MODE_(x) P_RATECONTROL_MODE "." D_VSTR(x)
|
||||||
|
#define P_RATECONTROL_TWOPASS P_RATECONTROL ".TwoPass"
|
||||||
|
#define P_RATECONTROL_LOOKAHEAD P_RATECONTROL ".LookAhead"
|
||||||
|
#define P_RATECONTROL_ADAPTIVEI P_RATECONTROL ".AdaptiveI"
|
||||||
|
#define P_RATECONTROL_ADAPTIVEB P_RATECONTROL ".AdaptiveB"
|
||||||
|
|
||||||
|
#define P_RATECONTROL_BITRATE P_RATECONTROL ".Bitrate"
|
||||||
|
#define P_RATECONTROL_BITRATE_TARGET P_RATECONTROL_BITRATE ".Target"
|
||||||
|
#define P_RATECONTROL_BITRATE_MAXIMUM P_RATECONTROL_BITRATE ".Maximum"
|
||||||
|
|
||||||
|
#define P_RATECONTROL_QUALITY P_RATECONTROL ".Quality"
|
||||||
|
#define P_RATECONTROL_QUALITY_MINIMUM P_RATECONTROL_QUALITY ".Minimum"
|
||||||
|
#define P_RATECONTROL_QUALITY_MAXIMUM P_RATECONTROL_QUALITY ".Maximum"
|
||||||
|
|
||||||
|
#define P_RATECONTROL_QP P_RATECONTROL ".QP"
|
||||||
|
#define P_RATECONTROL_QP_I P_RATECONTROL_QP ".I"
|
||||||
|
#define P_RATECONTROL_QP_I_INITIAL P_RATECONTROL_QP_I ".Initial"
|
||||||
|
#define P_RATECONTROL_QP_P P_RATECONTROL_QP ".P"
|
||||||
|
#define P_RATECONTROL_QP_P_INITIAL P_RATECONTROL_QP_P ".Initial"
|
||||||
|
#define P_RATECONTROL_QP_B P_RATECONTROL_QP ".B"
|
||||||
|
#define P_RATECONTROL_QP_B_INITIAL P_RATECONTROL_QP_B ".Initial"
|
||||||
|
|
||||||
|
#define P_AQ "NVENC.AQ"
|
||||||
|
#define P_AQ_SPATIAL P_AQ ".Spatial"
|
||||||
|
#define P_AQ_TEMPORAL P_AQ ".Temporal"
|
||||||
|
#define P_AQ_STRENGTH P_AQ ".Strength"
|
||||||
|
|
||||||
|
#define P_OTHER "NVENC.Other"
|
||||||
|
#define P_OTHER_BFRAMES P_OTHER ".BFrames"
|
||||||
|
#define P_OTHER_BFRAME_REFERENCEMODE P_OTHER ".BFrameReferenceMode"
|
||||||
|
#define P_OTHER_ZEROLATENCY P_OTHER ".ZeroLatency"
|
||||||
|
#define P_OTHER_WEIGHTED_PREDICTION P_OTHER ".WeightedPrediction"
|
||||||
|
#define P_OTHER_NONREFERENCE_PFRAMES P_OTHER ".NonReferencePFrames"
|
||||||
|
|
||||||
|
using namespace obsffmpeg::nvenc;
|
||||||
|
|
||||||
|
std::map<preset, std::string> obsffmpeg::nvenc::presets{
|
||||||
|
{preset::DEFAULT, P_PRESET_(Default)},
|
||||||
|
{preset::SLOW, P_PRESET_(Slow)},
|
||||||
|
{preset::MEDIUM, P_PRESET_(Medium)},
|
||||||
|
{preset::FAST, P_PRESET_(Fast)},
|
||||||
|
{preset::HIGH_PERFORMANCE, P_PRESET_(HighPerformance)},
|
||||||
|
{preset::HIGH_QUALITY, P_PRESET_(HighQuality)},
|
||||||
|
{preset::BLURAYDISC, P_PRESET_(BluRayDisc)},
|
||||||
|
{preset::LOW_LATENCY, P_PRESET_(LowLatency)},
|
||||||
|
{preset::LOW_LATENCY_HIGH_PERFORMANCE, P_PRESET_(LowLatencyHighPerformance)},
|
||||||
|
{preset::LOW_LATENCY_HIGH_QUALITY, P_PRESET_(LowLatencyHighQuality)},
|
||||||
|
{preset::LOSSLESS, P_PRESET_(Lossless)},
|
||||||
|
{preset::LOSSLESS_HIGH_PERFORMANCE, P_PRESET_(LosslessHighPerformance)},
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<preset, std::string> obsffmpeg::nvenc::preset_to_opt{
|
||||||
|
{preset::DEFAULT, "default"},
|
||||||
|
{preset::SLOW, "slow"},
|
||||||
|
{preset::MEDIUM, "medium"},
|
||||||
|
{preset::FAST, "fast"},
|
||||||
|
{preset::HIGH_PERFORMANCE, "hp"},
|
||||||
|
{preset::HIGH_QUALITY, "hq"},
|
||||||
|
{preset::BLURAYDISC, "bd"},
|
||||||
|
{preset::LOW_LATENCY, "ll"},
|
||||||
|
{preset::LOW_LATENCY_HIGH_PERFORMANCE, "llhp"},
|
||||||
|
{preset::LOW_LATENCY_HIGH_QUALITY, "llhq"},
|
||||||
|
{preset::LOSSLESS, "lossless"},
|
||||||
|
{preset::LOSSLESS_HIGH_PERFORMANCE, "losslesshp"},
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<ratecontrolmode, std::string> obsffmpeg::nvenc::ratecontrolmodes{
|
||||||
|
{ratecontrolmode::CQP, P_RATECONTROL_MODE_(CQP)},
|
||||||
|
{ratecontrolmode::VBR, P_RATECONTROL_MODE_(VBR)},
|
||||||
|
{ratecontrolmode::VBR_HQ, P_RATECONTROL_MODE_(VBR_HQ)},
|
||||||
|
{ratecontrolmode::CBR, P_RATECONTROL_MODE_(CBR)},
|
||||||
|
{ratecontrolmode::CBR_HQ, P_RATECONTROL_MODE_(CBR_HQ)},
|
||||||
|
{ratecontrolmode::CBR_LD_HQ, P_RATECONTROL_MODE_(CBR_LD_HQ)},
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<ratecontrolmode, std::string> obsffmpeg::nvenc::ratecontrolmode_to_opt{
|
||||||
|
{ratecontrolmode::CQP, "constqp"}, {ratecontrolmode::VBR, "vbr"}, {ratecontrolmode::VBR_HQ, "vbr_hq"},
|
||||||
|
{ratecontrolmode::CBR, "cbr"}, {ratecontrolmode::CBR_HQ, "cbr_hq"}, {ratecontrolmode::CBR_LD_HQ, "cbr_ld_hq"},
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<b_ref_mode, std::string> obsffmpeg::nvenc::b_ref_modes{
|
||||||
|
{b_ref_mode::DISABLED, G_STATE_DISABLED},
|
||||||
|
{b_ref_mode::EACH, P_OTHER_BFRAME_REFERENCEMODE ".Each"},
|
||||||
|
{b_ref_mode::MIDDLE, P_OTHER_BFRAME_REFERENCEMODE ".Middle"},
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<b_ref_mode, std::string> obsffmpeg::nvenc::b_ref_mode_to_opt{
|
||||||
|
{b_ref_mode::DISABLED, "disabled"},
|
||||||
|
{b_ref_mode::EACH, "each"},
|
||||||
|
{b_ref_mode::MIDDLE, "middle"},
|
||||||
|
};
|
||||||
|
|
||||||
|
void obsffmpeg::nvenc::get_defaults(obs_data_t* settings, AVCodec*, AVCodecContext*)
|
||||||
|
{
|
||||||
|
obs_data_set_default_int(settings, P_PRESET, static_cast<int64_t>(preset::DEFAULT));
|
||||||
|
|
||||||
|
obs_data_set_default_int(settings, P_RATECONTROL_MODE, static_cast<int64_t>(ratecontrolmode::CBR_HQ));
|
||||||
|
obs_data_set_default_int(settings, P_RATECONTROL_TWOPASS, -1);
|
||||||
|
obs_data_set_default_int(settings, P_RATECONTROL_LOOKAHEAD, 0);
|
||||||
|
obs_data_set_default_bool(settings, P_RATECONTROL_ADAPTIVEI, true);
|
||||||
|
obs_data_set_default_bool(settings, P_RATECONTROL_ADAPTIVEB, true);
|
||||||
|
|
||||||
|
obs_data_set_default_int(settings, P_RATECONTROL_BITRATE_TARGET, 6000);
|
||||||
|
obs_data_set_default_int(settings, P_RATECONTROL_BITRATE_MAXIMUM, 6000);
|
||||||
|
obs_data_set_default_int(settings, G_RATECONTROL_BUFFERSIZE, 12000);
|
||||||
|
|
||||||
|
obs_data_set_default_int(settings, P_RATECONTROL_QUALITY_MINIMUM, 51);
|
||||||
|
obs_data_set_default_int(settings, P_RATECONTROL_QUALITY_MAXIMUM, -1);
|
||||||
|
|
||||||
|
obs_data_set_default_int(settings, P_RATECONTROL_QP_I, 21);
|
||||||
|
obs_data_set_default_int(settings, P_RATECONTROL_QP_I_INITIAL, -1);
|
||||||
|
obs_data_set_default_int(settings, P_RATECONTROL_QP_P, 21);
|
||||||
|
obs_data_set_default_int(settings, P_RATECONTROL_QP_P_INITIAL, -1);
|
||||||
|
obs_data_set_default_int(settings, P_RATECONTROL_QP_B, 21);
|
||||||
|
obs_data_set_default_int(settings, P_RATECONTROL_QP_B_INITIAL, -1);
|
||||||
|
|
||||||
|
obs_data_set_default_int(settings, G_KEYFRAMES_INTERVALTYPE, 0);
|
||||||
|
obs_data_set_default_double(settings, G_KEYFRAMES_INTERVAL_SECONDS, 2.0);
|
||||||
|
obs_data_set_default_int(settings, G_KEYFRAMES_INTERVAL_FRAMES, 300);
|
||||||
|
|
||||||
|
obs_data_set_default_bool(settings, P_AQ_SPATIAL, true);
|
||||||
|
obs_data_set_default_int(settings, P_AQ_STRENGTH, 8);
|
||||||
|
obs_data_set_default_bool(settings, P_AQ_TEMPORAL, true);
|
||||||
|
|
||||||
|
obs_data_set_default_int(settings, P_OTHER_BFRAMES, 2);
|
||||||
|
obs_data_set_default_int(settings, P_OTHER_BFRAME_REFERENCEMODE, static_cast<int64_t>(b_ref_mode::DISABLED));
|
||||||
|
obs_data_set_default_bool(settings, P_OTHER_ZEROLATENCY, false);
|
||||||
|
obs_data_set_default_bool(settings, P_OTHER_WEIGHTED_PREDICTION, false);
|
||||||
|
obs_data_set_default_bool(settings, P_OTHER_NONREFERENCE_PFRAMES, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool modified_ratecontrol(obs_properties_t* props, obs_property_t*, obs_data_t* settings)
|
||||||
|
{
|
||||||
|
using namespace obsffmpeg::nvenc;
|
||||||
|
|
||||||
|
bool have_bitrate = false;
|
||||||
|
bool have_bitrate_max = false;
|
||||||
|
bool have_quality = false;
|
||||||
|
bool have_qp = false;
|
||||||
|
bool have_qp_init = false;
|
||||||
|
|
||||||
|
ratecontrolmode rc = static_cast<ratecontrolmode>(obs_data_get_int(settings, P_RATECONTROL_MODE));
|
||||||
|
switch (rc) {
|
||||||
|
case ratecontrolmode::CQP:
|
||||||
|
have_qp = true;
|
||||||
|
break;
|
||||||
|
case ratecontrolmode::CBR:
|
||||||
|
case ratecontrolmode::CBR_HQ:
|
||||||
|
case ratecontrolmode::CBR_LD_HQ:
|
||||||
|
have_bitrate = true;
|
||||||
|
break;
|
||||||
|
case ratecontrolmode::VBR:
|
||||||
|
case ratecontrolmode::VBR_HQ:
|
||||||
|
have_bitrate = true;
|
||||||
|
have_bitrate_max = true;
|
||||||
|
have_quality = true;
|
||||||
|
have_qp_init = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
obs_property_set_visible(obs_properties_get(props, P_RATECONTROL_BITRATE), have_bitrate || have_bitrate_max);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, P_RATECONTROL_BITRATE_TARGET), have_bitrate);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, P_RATECONTROL_BITRATE_MAXIMUM), have_bitrate_max);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, G_RATECONTROL_BUFFERSIZE), have_bitrate || have_bitrate_max);
|
||||||
|
|
||||||
|
obs_property_set_visible(obs_properties_get(props, P_RATECONTROL_QUALITY), have_quality);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, P_RATECONTROL_QUALITY_MINIMUM), have_quality);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, P_RATECONTROL_QUALITY_MAXIMUM), have_quality);
|
||||||
|
|
||||||
|
obs_property_set_visible(obs_properties_get(props, P_RATECONTROL_QP_I), have_qp);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, P_RATECONTROL_QP_P), have_qp);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, P_RATECONTROL_QP_B), have_qp);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, P_RATECONTROL_QP_I_INITIAL), have_qp_init);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, P_RATECONTROL_QP_P_INITIAL), have_qp_init);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, P_RATECONTROL_QP_B_INITIAL), have_qp_init);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool modified_quality(obs_properties_t* props, obs_property_t*, obs_data_t* settings)
|
||||||
|
{
|
||||||
|
bool enabled = obs_data_get_bool(settings, P_RATECONTROL_QUALITY);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_QUALITY_MINIMUM), enabled);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_QUALITY_MAXIMUM), enabled);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool modified_keyframes(obs_properties_t* props, obs_property_t*, obs_data_t* settings)
|
||||||
|
{
|
||||||
|
bool is_seconds = obs_data_get_int(settings, G_KEYFRAMES_INTERVALTYPE) == 0;
|
||||||
|
obs_property_set_visible(obs_properties_get(props, G_KEYFRAMES_INTERVAL_FRAMES), !is_seconds);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, G_KEYFRAMES_INTERVAL_SECONDS), is_seconds);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool modified_aq(obs_properties_t* props, obs_property_t*, obs_data_t* settings)
|
||||||
|
{
|
||||||
|
bool spatial_aq = obs_data_get_bool(settings, P_AQ_SPATIAL);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, P_AQ_STRENGTH), spatial_aq);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void obsffmpeg::nvenc::get_properties_pre(obs_properties_t* props, AVCodec*)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_list(props, P_PRESET, TRANSLATE(P_PRESET), OBS_COMBO_TYPE_LIST,
|
||||||
|
OBS_COMBO_FORMAT_INT);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_PRESET)));
|
||||||
|
for (auto kv : presets) {
|
||||||
|
obs_property_list_add_int(p, TRANSLATE(kv.second.c_str()), static_cast<int64_t>(kv.first));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void obsffmpeg::nvenc::get_properties_post(obs_properties_t* props, AVCodec* codec)
|
||||||
|
{
|
||||||
|
{ // Rate Control
|
||||||
|
obs_properties_t* grp = props;
|
||||||
|
if (!obsffmpeg::are_property_groups_broken()) {
|
||||||
|
grp = obs_properties_create();
|
||||||
|
obs_properties_add_group(props, P_RATECONTROL, TRANSLATE(P_RATECONTROL), OBS_GROUP_NORMAL, grp);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_list(grp, P_RATECONTROL_MODE, TRANSLATE(P_RATECONTROL_MODE),
|
||||||
|
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_RATECONTROL_MODE)));
|
||||||
|
obs_property_set_modified_callback(p, modified_ratecontrol);
|
||||||
|
for (auto kv : ratecontrolmodes) {
|
||||||
|
obs_property_list_add_int(p, TRANSLATE(kv.second.c_str()),
|
||||||
|
static_cast<int64_t>(kv.first));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_list(grp, P_RATECONTROL_TWOPASS, TRANSLATE(P_RATECONTROL_TWOPASS),
|
||||||
|
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_RATECONTROL_TWOPASS)));
|
||||||
|
obs_property_list_add_int(p, TRANSLATE(G_STATE_DEFAULT), -1);
|
||||||
|
obs_property_list_add_int(p, TRANSLATE(G_STATE_DISABLED), 0);
|
||||||
|
obs_property_list_add_int(p, TRANSLATE(G_STATE_ENABLED), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_int_slider(grp, P_RATECONTROL_LOOKAHEAD,
|
||||||
|
TRANSLATE(P_RATECONTROL_LOOKAHEAD), 0, 60, 1);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_RATECONTROL_LOOKAHEAD)));
|
||||||
|
obs_property_int_set_suffix(p, " frames");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto p =
|
||||||
|
obs_properties_add_bool(grp, P_RATECONTROL_ADAPTIVEI, TRANSLATE(P_RATECONTROL_ADAPTIVEI));
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_RATECONTROL_ADAPTIVEI)));
|
||||||
|
}
|
||||||
|
if (strcmp(codec->name, "h264_nvenc") == 0) {
|
||||||
|
auto p =
|
||||||
|
obs_properties_add_bool(grp, P_RATECONTROL_ADAPTIVEB, TRANSLATE(P_RATECONTROL_ADAPTIVEB));
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_RATECONTROL_ADAPTIVEB)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
obs_properties_t* grp = props;
|
||||||
|
if (!obsffmpeg::are_property_groups_broken()) {
|
||||||
|
grp = obs_properties_create();
|
||||||
|
obs_properties_add_group(props, P_RATECONTROL_BITRATE, TRANSLATE(P_RATECONTROL_BITRATE),
|
||||||
|
OBS_GROUP_NORMAL, grp);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_int(grp, P_RATECONTROL_BITRATE_TARGET,
|
||||||
|
TRANSLATE(P_RATECONTROL_BITRATE_TARGET), 1,
|
||||||
|
std::numeric_limits<int32_t>::max(), 1);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_RATECONTROL_BITRATE_TARGET)));
|
||||||
|
obs_property_int_set_suffix(p, " kbit/s");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_int(grp, P_RATECONTROL_BITRATE_MAXIMUM,
|
||||||
|
TRANSLATE(P_RATECONTROL_BITRATE_MAXIMUM), 0,
|
||||||
|
std::numeric_limits<int32_t>::max(), 1);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_RATECONTROL_BITRATE_MAXIMUM)));
|
||||||
|
obs_property_int_set_suffix(p, " kbit/s");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto p =
|
||||||
|
obs_properties_add_int(grp, G_RATECONTROL_BUFFERSIZE, TRANSLATE(G_RATECONTROL_BUFFERSIZE),
|
||||||
|
0, std::numeric_limits<int32_t>::max(), 1);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(G_RATECONTROL_BUFFERSIZE)));
|
||||||
|
obs_property_int_set_suffix(p, " kbit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
obs_properties_t* grp = props;
|
||||||
|
if (!obsffmpeg::are_property_groups_broken()) {
|
||||||
|
grp = obs_properties_create();
|
||||||
|
auto p = obs_properties_add_group(props, P_RATECONTROL_QUALITY,
|
||||||
|
TRANSLATE(P_RATECONTROL_QUALITY), OBS_GROUP_CHECKABLE, grp);
|
||||||
|
obs_property_set_modified_callback(p, modified_quality);
|
||||||
|
} else {
|
||||||
|
auto p =
|
||||||
|
obs_properties_add_bool(props, P_RATECONTROL_QUALITY, TRANSLATE(P_RATECONTROL_QUALITY));
|
||||||
|
obs_property_set_modified_callback(p, modified_quality);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_int_slider(grp, P_RATECONTROL_QUALITY_MINIMUM,
|
||||||
|
TRANSLATE(P_RATECONTROL_QUALITY_MINIMUM), 0, 51, 1);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_RATECONTROL_QUALITY_MINIMUM)));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_int_slider(grp, P_RATECONTROL_QUALITY_MAXIMUM,
|
||||||
|
TRANSLATE(P_RATECONTROL_QUALITY_MAXIMUM), -1, 51, 1);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_RATECONTROL_QUALITY_MAXIMUM)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
obs_properties_t* grp = props;
|
||||||
|
if (!obsffmpeg::are_property_groups_broken()) {
|
||||||
|
grp = obs_properties_create();
|
||||||
|
auto p = obs_properties_add_group(props, P_RATECONTROL_QP, TRANSLATE(P_RATECONTROL_QP),
|
||||||
|
OBS_GROUP_CHECKABLE, grp);
|
||||||
|
obs_property_set_modified_callback(p, modified_quality);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_int_slider(grp, P_RATECONTROL_QP_I, TRANSLATE(P_RATECONTROL_QP_I),
|
||||||
|
0, 51, 1);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_RATECONTROL_QP_I)));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_int_slider(grp, P_RATECONTROL_QP_I_INITIAL,
|
||||||
|
TRANSLATE(P_RATECONTROL_QP_I_INITIAL), -1, 51, 1);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_RATECONTROL_QP_I_INITIAL)));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_int_slider(grp, P_RATECONTROL_QP_P, TRANSLATE(P_RATECONTROL_QP_P),
|
||||||
|
0, 51, 1);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_RATECONTROL_QP_P)));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_int_slider(grp, P_RATECONTROL_QP_P_INITIAL,
|
||||||
|
TRANSLATE(P_RATECONTROL_QP_P_INITIAL), -1, 51, 1);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_RATECONTROL_QP_P_INITIAL)));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_int_slider(grp, P_RATECONTROL_QP_B, TRANSLATE(P_RATECONTROL_QP_B),
|
||||||
|
0, 51, 1);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_RATECONTROL_QP_B)));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_int_slider(grp, P_RATECONTROL_QP_B_INITIAL,
|
||||||
|
TRANSLATE(P_RATECONTROL_QP_B_INITIAL), -1, 51, 1);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_RATECONTROL_QP_B_INITIAL)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
obs_properties_t* grp = props;
|
||||||
|
if (!obsffmpeg::are_property_groups_broken()) {
|
||||||
|
grp = obs_properties_create();
|
||||||
|
obs_properties_add_group(props, G_KEYFRAMES, TRANSLATE(G_KEYFRAMES), OBS_GROUP_NORMAL, grp);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p =
|
||||||
|
obs_properties_add_list(grp, G_KEYFRAMES_INTERVALTYPE, TRANSLATE(G_KEYFRAMES_INTERVALTYPE),
|
||||||
|
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(G_KEYFRAMES_INTERVALTYPE)));
|
||||||
|
obs_property_set_modified_callback(p, modified_keyframes);
|
||||||
|
obs_property_list_add_int(p, TRANSLATE(G_KEYFRAMES_INTERVALTYPE_(Seconds)), 0);
|
||||||
|
obs_property_list_add_int(p, TRANSLATE(G_KEYFRAMES_INTERVALTYPE_(Frames)), 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto p =
|
||||||
|
obs_properties_add_float(grp, G_KEYFRAMES_INTERVAL_SECONDS, TRANSLATE(G_KEYFRAMES_INTERVAL),
|
||||||
|
0.00, std::numeric_limits<int16_t>::max(), 0.01);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(G_KEYFRAMES_INTERVAL)));
|
||||||
|
obs_property_float_set_suffix(p, " seconds");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto p =
|
||||||
|
obs_properties_add_int(grp, G_KEYFRAMES_INTERVAL_FRAMES, TRANSLATE(G_KEYFRAMES_INTERVAL), 0,
|
||||||
|
std::numeric_limits<int32_t>::max(), 1);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(G_KEYFRAMES_INTERVAL)));
|
||||||
|
obs_property_int_set_suffix(p, " frames");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
obs_properties_t* grp = props;
|
||||||
|
if (!obsffmpeg::are_property_groups_broken()) {
|
||||||
|
grp = obs_properties_create();
|
||||||
|
obs_properties_add_group(props, P_AQ, TRANSLATE(P_AQ), OBS_GROUP_NORMAL, grp);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_bool(grp, P_AQ_SPATIAL, TRANSLATE(P_AQ_SPATIAL));
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_AQ_SPATIAL)));
|
||||||
|
obs_property_set_modified_callback(p, modified_aq);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_int_slider(grp, P_AQ_STRENGTH, TRANSLATE(P_AQ_STRENGTH), 1, 15, 1);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_AQ_STRENGTH)));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_bool(grp, P_AQ_TEMPORAL, TRANSLATE(P_AQ_TEMPORAL));
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_AQ_TEMPORAL)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
obs_properties_t* grp = props;
|
||||||
|
if (!obsffmpeg::are_property_groups_broken()) {
|
||||||
|
grp = obs_properties_create();
|
||||||
|
obs_properties_add_group(props, P_OTHER, TRANSLATE(P_OTHER), OBS_GROUP_NORMAL, grp);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p =
|
||||||
|
obs_properties_add_int_slider(grp, P_OTHER_BFRAMES, TRANSLATE(P_OTHER_BFRAMES), 0, 4, 1);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_OTHER_BFRAMES)));
|
||||||
|
obs_property_int_set_suffix(p, " frames");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_list(grp, P_OTHER_BFRAME_REFERENCEMODE,
|
||||||
|
TRANSLATE(P_OTHER_BFRAME_REFERENCEMODE), OBS_COMBO_TYPE_LIST,
|
||||||
|
OBS_COMBO_FORMAT_INT);
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_OTHER_BFRAME_REFERENCEMODE)));
|
||||||
|
for (auto kv : b_ref_modes) {
|
||||||
|
obs_property_list_add_int(p, TRANSLATE(kv.second.c_str()),
|
||||||
|
static_cast<int64_t>(kv.first));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_bool(grp, P_OTHER_ZEROLATENCY, TRANSLATE(P_OTHER_ZEROLATENCY));
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_OTHER_ZEROLATENCY)));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_bool(grp, P_OTHER_WEIGHTED_PREDICTION,
|
||||||
|
TRANSLATE(P_OTHER_WEIGHTED_PREDICTION));
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_OTHER_WEIGHTED_PREDICTION)));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p = obs_properties_add_bool(grp, P_OTHER_NONREFERENCE_PFRAMES,
|
||||||
|
TRANSLATE(P_OTHER_NONREFERENCE_PFRAMES));
|
||||||
|
obs_property_set_long_description(p, TRANSLATE(DESC(P_OTHER_NONREFERENCE_PFRAMES)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void obsffmpeg::nvenc::get_runtime_properties(obs_properties_t* props, AVCodec*, AVCodecContext*)
|
||||||
|
{
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_PRESET), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_MODE), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_TWOPASS), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_LOOKAHEAD), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_ADAPTIVEI), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_ADAPTIVEB), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_BITRATE), true);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_BITRATE_TARGET), true);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_BITRATE_MAXIMUM), true);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, G_RATECONTROL_BUFFERSIZE), true);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_QUALITY), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_QUALITY_MINIMUM), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_QUALITY_MAXIMUM), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_QP), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_QP_I), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_QP_I_INITIAL), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_QP_P), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_QP_P_INITIAL), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_QP_B), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL_QP_B_INITIAL), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, G_KEYFRAMES), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, G_KEYFRAMES_INTERVALTYPE), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, G_KEYFRAMES_INTERVAL_SECONDS), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, G_KEYFRAMES_INTERVAL_FRAMES), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_AQ), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_AQ_SPATIAL), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_AQ_STRENGTH), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_AQ_TEMPORAL), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_OTHER), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_OTHER_BFRAMES), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_OTHER_BFRAME_REFERENCEMODE), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_OTHER_ZEROLATENCY), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_OTHER_WEIGHTED_PREDICTION), false);
|
||||||
|
obs_property_set_enabled(obs_properties_get(props, P_OTHER_NONREFERENCE_PFRAMES), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void obsffmpeg::nvenc::update(obs_data_t* settings, AVCodec* codec, AVCodecContext* context)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
preset c_preset = static_cast<preset>(obs_data_get_int(settings, P_PRESET));
|
||||||
|
auto found = preset_to_opt.find(c_preset);
|
||||||
|
if (found != preset_to_opt.end()) {
|
||||||
|
av_opt_set(context->priv_data, "preset", found->second.c_str(), 0);
|
||||||
|
} else {
|
||||||
|
av_opt_set(context->priv_data, "preset", nullptr, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Rate Control
|
||||||
|
bool have_bitrate = false;
|
||||||
|
bool have_bitrate_max = false;
|
||||||
|
bool have_quality_min = false;
|
||||||
|
bool have_quality_max = false;
|
||||||
|
bool have_qp = false;
|
||||||
|
bool have_qp_init = false;
|
||||||
|
|
||||||
|
ratecontrolmode rc = static_cast<ratecontrolmode>(obs_data_get_int(settings, P_RATECONTROL_MODE));
|
||||||
|
auto rcopt = nvenc::ratecontrolmode_to_opt.find(rc);
|
||||||
|
if (rcopt != nvenc::ratecontrolmode_to_opt.end()) {
|
||||||
|
av_opt_set(context->priv_data, "rc", rcopt->second.c_str(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (rc) {
|
||||||
|
case ratecontrolmode::CQP:
|
||||||
|
have_qp = true;
|
||||||
|
break;
|
||||||
|
case ratecontrolmode::CBR:
|
||||||
|
case ratecontrolmode::CBR_HQ:
|
||||||
|
case ratecontrolmode::CBR_LD_HQ:
|
||||||
|
have_bitrate = true;
|
||||||
|
av_opt_set_int(context->priv_data, "cbr", 1, 0);
|
||||||
|
break;
|
||||||
|
case ratecontrolmode::VBR:
|
||||||
|
case ratecontrolmode::VBR_HQ:
|
||||||
|
have_bitrate_max = true;
|
||||||
|
have_bitrate = true;
|
||||||
|
have_quality_min = true;
|
||||||
|
have_quality_max = true;
|
||||||
|
have_qp_init = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tp = static_cast<int>(obs_data_get_int(settings, P_RATECONTROL_TWOPASS));
|
||||||
|
if (tp >= 0) {
|
||||||
|
av_opt_set_int(context->priv_data, "2pass", tp ? 1 : 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int la = static_cast<int>(obs_data_get_int(settings, P_RATECONTROL_LOOKAHEAD));
|
||||||
|
av_opt_set_int(context->priv_data, "lookahead", la, 0);
|
||||||
|
if (la > 0) {
|
||||||
|
bool adapt_i = obs_data_get_bool(settings, P_RATECONTROL_ADAPTIVEI);
|
||||||
|
av_opt_set_int(context->priv_data, "no-scenecut", !adapt_i ? 1 : 0, 0);
|
||||||
|
|
||||||
|
if (strcmp(codec->name, "h264_nvenc")) {
|
||||||
|
bool adapt_b = obs_data_get_bool(settings, P_RATECONTROL_ADAPTIVEB);
|
||||||
|
av_opt_set_int(context->priv_data, "b_adapt", adapt_b ? 1 : 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have_bitrate)
|
||||||
|
context->bit_rate =
|
||||||
|
static_cast<int>(obs_data_get_int(settings, P_RATECONTROL_BITRATE_TARGET) * 1000);
|
||||||
|
if (have_bitrate_max)
|
||||||
|
context->rc_max_rate =
|
||||||
|
static_cast<int>(obs_data_get_int(settings, P_RATECONTROL_BITRATE_MAXIMUM) * 1000);
|
||||||
|
if (have_bitrate || have_bitrate_max)
|
||||||
|
context->rc_buffer_size =
|
||||||
|
static_cast<int>(obs_data_get_int(settings, G_RATECONTROL_BUFFERSIZE) * 1000);
|
||||||
|
|
||||||
|
if (have_quality_min && obs_data_get_bool(settings, P_RATECONTROL_QUALITY)) {
|
||||||
|
int qmin = static_cast<int>(obs_data_get_int(settings, P_RATECONTROL_QUALITY_MINIMUM));
|
||||||
|
context->qmin = qmin;
|
||||||
|
if ((qmin >= 0) && (have_quality_max)) {
|
||||||
|
context->qmax =
|
||||||
|
static_cast<int>(obs_data_get_int(settings, P_RATECONTROL_QUALITY_MAXIMUM));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have_qp) {
|
||||||
|
av_opt_set_int(context->priv_data, "init_qpI",
|
||||||
|
static_cast<int>(obs_data_get_int(settings, P_RATECONTROL_QP_I)), 0);
|
||||||
|
av_opt_set_int(context->priv_data, "init_qpP",
|
||||||
|
static_cast<int>(obs_data_get_int(settings, P_RATECONTROL_QP_P)), 0);
|
||||||
|
av_opt_set_int(context->priv_data, "init_qpB",
|
||||||
|
static_cast<int>(obs_data_get_int(settings, P_RATECONTROL_QP_B)), 0);
|
||||||
|
}
|
||||||
|
if (have_qp_init) {
|
||||||
|
av_opt_set_int(context->priv_data, "init_qpI",
|
||||||
|
obs_data_get_int(settings, P_RATECONTROL_QP_I_INITIAL), 0);
|
||||||
|
av_opt_set_int(context->priv_data, "init_qpP",
|
||||||
|
obs_data_get_int(settings, P_RATECONTROL_QP_P_INITIAL), 0);
|
||||||
|
av_opt_set_int(context->priv_data, "init_qpB",
|
||||||
|
obs_data_get_int(settings, P_RATECONTROL_QP_B_INITIAL), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Key Frames
|
||||||
|
obs_video_info ovi;
|
||||||
|
if (!obs_get_video_info(&ovi)) {
|
||||||
|
throw std::runtime_error("no video info");
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t kf_type = obs_data_get_int(settings, G_KEYFRAMES_INTERVALTYPE);
|
||||||
|
bool is_seconds = (kf_type == 0);
|
||||||
|
|
||||||
|
if (is_seconds) {
|
||||||
|
context->gop_size = static_cast<int>(obs_data_get_double(settings, G_KEYFRAMES_INTERVAL_SECONDS)
|
||||||
|
* (ovi.fps_num / ovi.fps_den));
|
||||||
|
} else {
|
||||||
|
context->gop_size = static_cast<int>(obs_data_get_int(settings, G_KEYFRAMES_INTERVAL_FRAMES));
|
||||||
|
}
|
||||||
|
context->keyint_min = context->gop_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // AQ
|
||||||
|
bool saq = obs_data_get_bool(settings, P_AQ_SPATIAL);
|
||||||
|
bool taq = obs_data_get_bool(settings, P_AQ_TEMPORAL);
|
||||||
|
|
||||||
|
if (strcmp(codec->name, "h264_nvenc")) {
|
||||||
|
av_opt_set_int(context->priv_data, "spatial-aq", saq ? 1 : 0, 0);
|
||||||
|
av_opt_set_int(context->priv_data, "temporal-aq", taq ? 1 : 0, 0);
|
||||||
|
} else {
|
||||||
|
av_opt_set_int(context->priv_data, "spatial_aq", saq ? 1 : 0, 0);
|
||||||
|
av_opt_set_int(context->priv_data, "temporal_aq", taq ? 1 : 0, 0);
|
||||||
|
}
|
||||||
|
if (saq) {
|
||||||
|
av_opt_set_int(context->priv_data, "aq-strength",
|
||||||
|
static_cast<int>(obs_data_get_int(settings, P_AQ_STRENGTH)), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Other
|
||||||
|
bool zl = obs_data_get_bool(settings, P_OTHER_ZEROLATENCY);
|
||||||
|
bool wp = obs_data_get_bool(settings, P_OTHER_WEIGHTED_PREDICTION);
|
||||||
|
bool nrp = obs_data_get_bool(settings, P_OTHER_NONREFERENCE_PFRAMES);
|
||||||
|
|
||||||
|
context->max_b_frames = static_cast<int>(obs_data_get_int(settings, P_OTHER_BFRAMES));
|
||||||
|
|
||||||
|
av_opt_set_int(context->priv_data, "zerolatency", zl ? 1 : 0, 0);
|
||||||
|
av_opt_set_int(context->priv_data, "nonref_p", nrp ? 1 : 0, 0);
|
||||||
|
|
||||||
|
if ((context->max_b_frames != 0) && wp) {
|
||||||
|
PLOG_WARNING(
|
||||||
|
"Automatically disabled weighted prediction due to being incompatible with B-Frames.");
|
||||||
|
} else {
|
||||||
|
av_opt_set_int(context->priv_data, "weighted_pred", wp ? 1 : 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto found = b_ref_mode_to_opt.find(
|
||||||
|
static_cast<b_ref_mode>(obs_data_get_int(settings, P_OTHER_BFRAME_REFERENCEMODE)));
|
||||||
|
if (found != b_ref_mode_to_opt.end()) {
|
||||||
|
av_opt_set(context->priv_data, "b_ref_mode", found->second.c_str(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <map>
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <obs-properties.h>
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4244)
|
||||||
|
#include <libavcodec/avcodec.h>
|
||||||
|
#pragma warning(pop)
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace obsffmpeg {
|
||||||
|
namespace nvenc {
|
||||||
|
enum class preset : int64_t {
|
||||||
|
DEFAULT,
|
||||||
|
SLOW,
|
||||||
|
MEDIUM,
|
||||||
|
FAST,
|
||||||
|
HIGH_PERFORMANCE,
|
||||||
|
HIGH_QUALITY,
|
||||||
|
BLURAYDISC,
|
||||||
|
LOW_LATENCY,
|
||||||
|
LOW_LATENCY_HIGH_PERFORMANCE,
|
||||||
|
LOW_LATENCY_HIGH_QUALITY,
|
||||||
|
LOSSLESS,
|
||||||
|
LOSSLESS_HIGH_PERFORMANCE,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ratecontrolmode : int64_t {
|
||||||
|
CQP,
|
||||||
|
VBR,
|
||||||
|
VBR_HQ,
|
||||||
|
CBR,
|
||||||
|
CBR_HQ,
|
||||||
|
CBR_LD_HQ,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class b_ref_mode : int64_t {
|
||||||
|
DISABLED,
|
||||||
|
EACH,
|
||||||
|
MIDDLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern std::map<preset, std::string> presets;
|
||||||
|
|
||||||
|
extern std::map<preset, std::string> preset_to_opt;
|
||||||
|
|
||||||
|
extern std::map<ratecontrolmode, std::string> ratecontrolmodes;
|
||||||
|
|
||||||
|
extern std::map<ratecontrolmode, std::string> ratecontrolmode_to_opt;
|
||||||
|
|
||||||
|
extern std::map<b_ref_mode, std::string> b_ref_modes;
|
||||||
|
|
||||||
|
extern std::map<b_ref_mode, std::string> b_ref_mode_to_opt;
|
||||||
|
|
||||||
|
void get_defaults(obs_data_t* settings, AVCodec* codec, AVCodecContext* context);
|
||||||
|
|
||||||
|
void get_properties_pre(obs_properties_t* props, AVCodec* codec);
|
||||||
|
|
||||||
|
void get_properties_post(obs_properties_t* props, AVCodec* codec);
|
||||||
|
|
||||||
|
void get_runtime_properties(obs_properties_t* props, AVCodec* codec, AVCodecContext* context);
|
||||||
|
|
||||||
|
void update(obs_data_t* settings, AVCodec* codec, AVCodecContext* context);
|
||||||
|
} // namespace nvenc
|
||||||
|
} // namespace obsffmpeg
|
||||||
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2019 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#include "prores_aw_handler.hpp"
|
#include "prores_aw_handler.hpp"
|
||||||
#include "plugin.hpp"
|
#include "plugin.hpp"
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2019 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "handler.hpp"
|
#include "handler.hpp"
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|||||||
+29
-12
@@ -1,24 +1,33 @@
|
|||||||
// FFMPEG Video Encoder Integration for OBS Studio
|
// FFMPEG Video Encoder Integration for OBS Studio
|
||||||
// Copyright (C) 2018 - 2018 Michael Fabian Dirks
|
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// it under the terms of the GNU General Public License as published by
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// in the Software without restriction, including without limitation the rights
|
||||||
// (at your option) any later version.
|
// 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:
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// copies or substantial portions of the Software.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// along with this program; if not, write to the Free Software
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// 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.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <obs-config.h>
|
||||||
|
#include <obs.h>
|
||||||
|
}
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
#define PLOG(level, ...) blog(level, "[obs-ffmpeg-encoder] " __VA_ARGS__);
|
#define PLOG(level, ...) blog(level, "[obs-ffmpeg-encoder] " __VA_ARGS__);
|
||||||
#define PLOG_ERROR(...) PLOG(LOG_ERROR, __VA_ARGS__)
|
#define PLOG_ERROR(...) PLOG(LOG_ERROR, __VA_ARGS__)
|
||||||
@@ -71,3 +80,11 @@
|
|||||||
static void f(void) __attribute__((constructor)); \
|
static void f(void) __attribute__((constructor)); \
|
||||||
static void f(void)
|
static void f(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
namespace obsffmpeg {
|
||||||
|
bool inline are_property_groups_broken()
|
||||||
|
{
|
||||||
|
return obs_get_version() < MAKE_SEMANTIC_VERSION(24, 0, 0);
|
||||||
|
}
|
||||||
|
} // namespace obsffmpeg
|
||||||
|
|||||||
Reference in New Issue
Block a user