mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-18 22:18:19 +00:00
2279: Only forbid resizing when videorecorder is recording r=heinrich5991 a=def- 2327: List data files in `CMakeLists.txt` r=def- a=heinrich5991 This fixes missing files for people recompiling when we add new data files. Co-authored-by: def <dennis@felsin9.de> Co-authored-by: heinrich5991 <heinrich5991@gmail.com>
This commit is contained in:
commit
160a7b71fb
735
CMakeLists.txt
735
CMakeLists.txt
|
@ -571,11 +571,744 @@ if(NOT CRYPTO_FOUND)
|
||||||
set(DEP_MD5 $<TARGET_OBJECTS:md5>)
|
set(DEP_MD5 $<TARGET_OBJECTS:md5>)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# DATA
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
set(EXPECTED_DATA
|
||||||
|
arrow.png
|
||||||
|
audio/foley_body_impact-01.wv
|
||||||
|
audio/foley_body_impact-02.wv
|
||||||
|
audio/foley_body_impact-03.wv
|
||||||
|
audio/foley_body_splat-01.wv
|
||||||
|
audio/foley_body_splat-02.wv
|
||||||
|
audio/foley_body_splat-03.wv
|
||||||
|
audio/foley_body_splat-04.wv
|
||||||
|
audio/foley_dbljump-01.wv
|
||||||
|
audio/foley_dbljump-02.wv
|
||||||
|
audio/foley_dbljump-03.wv
|
||||||
|
audio/foley_foot_left-01.wv
|
||||||
|
audio/foley_foot_left-02.wv
|
||||||
|
audio/foley_foot_left-03.wv
|
||||||
|
audio/foley_foot_left-04.wv
|
||||||
|
audio/foley_foot_right-01.wv
|
||||||
|
audio/foley_foot_right-02.wv
|
||||||
|
audio/foley_foot_right-03.wv
|
||||||
|
audio/foley_foot_right-04.wv
|
||||||
|
audio/foley_land-01.wv
|
||||||
|
audio/foley_land-02.wv
|
||||||
|
audio/foley_land-03.wv
|
||||||
|
audio/foley_land-04.wv
|
||||||
|
audio/hook_attach-01.wv
|
||||||
|
audio/hook_attach-02.wv
|
||||||
|
audio/hook_attach-03.wv
|
||||||
|
audio/hook_loop-01.wv
|
||||||
|
audio/hook_loop-02.wv
|
||||||
|
audio/hook_noattach-01.wv
|
||||||
|
audio/hook_noattach-02.wv
|
||||||
|
audio/hook_noattach-03.wv
|
||||||
|
audio/music_menu.wv
|
||||||
|
audio/sfx_ctf_cap_pl.wv
|
||||||
|
audio/sfx_ctf_drop.wv
|
||||||
|
audio/sfx_ctf_grab_en.wv
|
||||||
|
audio/sfx_ctf_grab_pl.wv
|
||||||
|
audio/sfx_ctf_rtn.wv
|
||||||
|
audio/sfx_hit_strong-01.wv
|
||||||
|
audio/sfx_hit_strong-02.wv
|
||||||
|
audio/sfx_hit_weak-01.wv
|
||||||
|
audio/sfx_hit_weak-02.wv
|
||||||
|
audio/sfx_hit_weak-03.wv
|
||||||
|
audio/sfx_msg-client.wv
|
||||||
|
audio/sfx_msg-highlight.wv
|
||||||
|
audio/sfx_msg-server.wv
|
||||||
|
audio/sfx_pickup_arm-01.wv
|
||||||
|
audio/sfx_pickup_arm-02.wv
|
||||||
|
audio/sfx_pickup_arm-03.wv
|
||||||
|
audio/sfx_pickup_arm-04.wv
|
||||||
|
audio/sfx_pickup_gun.wv
|
||||||
|
audio/sfx_pickup_hrt-01.wv
|
||||||
|
audio/sfx_pickup_hrt-02.wv
|
||||||
|
audio/sfx_pickup_launcher.wv
|
||||||
|
audio/sfx_pickup_ninja.wv
|
||||||
|
audio/sfx_pickup_sg.wv
|
||||||
|
audio/sfx_skid-01.wv
|
||||||
|
audio/sfx_skid-02.wv
|
||||||
|
audio/sfx_skid-03.wv
|
||||||
|
audio/sfx_skid-04.wv
|
||||||
|
audio/sfx_spawn_wpn-01.wv
|
||||||
|
audio/sfx_spawn_wpn-02.wv
|
||||||
|
audio/sfx_spawn_wpn-03.wv
|
||||||
|
audio/vo_teefault_cry-01.wv
|
||||||
|
audio/vo_teefault_cry-02.wv
|
||||||
|
audio/vo_teefault_ninja-01.wv
|
||||||
|
audio/vo_teefault_ninja-02.wv
|
||||||
|
audio/vo_teefault_ninja-03.wv
|
||||||
|
audio/vo_teefault_ninja-04.wv
|
||||||
|
audio/vo_teefault_pain_long-01.wv
|
||||||
|
audio/vo_teefault_pain_long-02.wv
|
||||||
|
audio/vo_teefault_pain_short-01.wv
|
||||||
|
audio/vo_teefault_pain_short-02.wv
|
||||||
|
audio/vo_teefault_pain_short-03.wv
|
||||||
|
audio/vo_teefault_pain_short-04.wv
|
||||||
|
audio/vo_teefault_pain_short-05.wv
|
||||||
|
audio/vo_teefault_pain_short-06.wv
|
||||||
|
audio/vo_teefault_pain_short-07.wv
|
||||||
|
audio/vo_teefault_pain_short-08.wv
|
||||||
|
audio/vo_teefault_pain_short-09.wv
|
||||||
|
audio/vo_teefault_pain_short-10.wv
|
||||||
|
audio/vo_teefault_pain_short-11.wv
|
||||||
|
audio/vo_teefault_pain_short-12.wv
|
||||||
|
audio/vo_teefault_sledge-01.wv
|
||||||
|
audio/vo_teefault_sledge-02.wv
|
||||||
|
audio/vo_teefault_sledge-03.wv
|
||||||
|
audio/vo_teefault_spawn-01.wv
|
||||||
|
audio/vo_teefault_spawn-02.wv
|
||||||
|
audio/vo_teefault_spawn-03.wv
|
||||||
|
audio/vo_teefault_spawn-04.wv
|
||||||
|
audio/vo_teefault_spawn-05.wv
|
||||||
|
audio/vo_teefault_spawn-06.wv
|
||||||
|
audio/vo_teefault_spawn-07.wv
|
||||||
|
audio/wp_flump_explo-01.wv
|
||||||
|
audio/wp_flump_explo-02.wv
|
||||||
|
audio/wp_flump_explo-03.wv
|
||||||
|
audio/wp_flump_launch-01.wv
|
||||||
|
audio/wp_flump_launch-02.wv
|
||||||
|
audio/wp_flump_launch-03.wv
|
||||||
|
audio/wp_gun_fire-01.wv
|
||||||
|
audio/wp_gun_fire-02.wv
|
||||||
|
audio/wp_gun_fire-03.wv
|
||||||
|
audio/wp_hammer_hit-01.wv
|
||||||
|
audio/wp_hammer_hit-02.wv
|
||||||
|
audio/wp_hammer_hit-03.wv
|
||||||
|
audio/wp_hammer_swing-01.wv
|
||||||
|
audio/wp_hammer_swing-02.wv
|
||||||
|
audio/wp_hammer_swing-03.wv
|
||||||
|
audio/wp_laser_bnce-01.wv
|
||||||
|
audio/wp_laser_bnce-02.wv
|
||||||
|
audio/wp_laser_bnce-03.wv
|
||||||
|
audio/wp_laser_fire-01.wv
|
||||||
|
audio/wp_laser_fire-02.wv
|
||||||
|
audio/wp_laser_fire-03.wv
|
||||||
|
audio/wp_ninja_attack-01.wv
|
||||||
|
audio/wp_ninja_attack-02.wv
|
||||||
|
audio/wp_ninja_attack-03.wv
|
||||||
|
audio/wp_ninja_attack-04.wv
|
||||||
|
audio/wp_ninja_hit-01.wv
|
||||||
|
audio/wp_ninja_hit-02.wv
|
||||||
|
audio/wp_ninja_hit-03.wv
|
||||||
|
audio/wp_ninja_hit-04.wv
|
||||||
|
audio/wp_noammo-01.wv
|
||||||
|
audio/wp_noammo-02.wv
|
||||||
|
audio/wp_noammo-03.wv
|
||||||
|
audio/wp_noammo-04.wv
|
||||||
|
audio/wp_noammo-05.wv
|
||||||
|
audio/wp_shotty_fire-01.wv
|
||||||
|
audio/wp_shotty_fire-02.wv
|
||||||
|
audio/wp_shotty_fire-03.wv
|
||||||
|
audio/wp_switch-01.wv
|
||||||
|
audio/wp_switch-02.wv
|
||||||
|
audio/wp_switch-03.wv
|
||||||
|
blob.png
|
||||||
|
browse_icons.png
|
||||||
|
ca-ddnet.pem
|
||||||
|
console.png
|
||||||
|
console_bar.png
|
||||||
|
countryflags/AD.png
|
||||||
|
countryflags/AE.png
|
||||||
|
countryflags/AF.png
|
||||||
|
countryflags/AG.png
|
||||||
|
countryflags/AI.png
|
||||||
|
countryflags/AL.png
|
||||||
|
countryflags/AM.png
|
||||||
|
countryflags/AO.png
|
||||||
|
countryflags/AR.png
|
||||||
|
countryflags/AS.png
|
||||||
|
countryflags/AT.png
|
||||||
|
countryflags/AU.png
|
||||||
|
countryflags/AW.png
|
||||||
|
countryflags/AX.png
|
||||||
|
countryflags/AZ.png
|
||||||
|
countryflags/BA.png
|
||||||
|
countryflags/BB.png
|
||||||
|
countryflags/BD.png
|
||||||
|
countryflags/BE.png
|
||||||
|
countryflags/BF.png
|
||||||
|
countryflags/BG.png
|
||||||
|
countryflags/BH.png
|
||||||
|
countryflags/BI.png
|
||||||
|
countryflags/BJ.png
|
||||||
|
countryflags/BL.png
|
||||||
|
countryflags/BM.png
|
||||||
|
countryflags/BN.png
|
||||||
|
countryflags/BO.png
|
||||||
|
countryflags/BR.png
|
||||||
|
countryflags/BS.png
|
||||||
|
countryflags/BT.png
|
||||||
|
countryflags/BW.png
|
||||||
|
countryflags/BY.png
|
||||||
|
countryflags/BZ.png
|
||||||
|
countryflags/CA.png
|
||||||
|
countryflags/CC.png
|
||||||
|
countryflags/CD.png
|
||||||
|
countryflags/CF.png
|
||||||
|
countryflags/CG.png
|
||||||
|
countryflags/CH.png
|
||||||
|
countryflags/CI.png
|
||||||
|
countryflags/CK.png
|
||||||
|
countryflags/CL.png
|
||||||
|
countryflags/CM.png
|
||||||
|
countryflags/CN.png
|
||||||
|
countryflags/CO.png
|
||||||
|
countryflags/CR.png
|
||||||
|
countryflags/CU.png
|
||||||
|
countryflags/CV.png
|
||||||
|
countryflags/CW.png
|
||||||
|
countryflags/CX.png
|
||||||
|
countryflags/CY.png
|
||||||
|
countryflags/CZ.png
|
||||||
|
countryflags/DE.png
|
||||||
|
countryflags/DJ.png
|
||||||
|
countryflags/DK.png
|
||||||
|
countryflags/DM.png
|
||||||
|
countryflags/DO.png
|
||||||
|
countryflags/DZ.png
|
||||||
|
countryflags/EC.png
|
||||||
|
countryflags/EE.png
|
||||||
|
countryflags/EG.png
|
||||||
|
countryflags/EH.png
|
||||||
|
countryflags/ER.png
|
||||||
|
countryflags/ES.png
|
||||||
|
countryflags/ET.png
|
||||||
|
countryflags/FI.png
|
||||||
|
countryflags/FJ.png
|
||||||
|
countryflags/FK.png
|
||||||
|
countryflags/FM.png
|
||||||
|
countryflags/FO.png
|
||||||
|
countryflags/FR.png
|
||||||
|
countryflags/GA.png
|
||||||
|
countryflags/GB.png
|
||||||
|
countryflags/GD.png
|
||||||
|
countryflags/GE.png
|
||||||
|
countryflags/GF.png
|
||||||
|
countryflags/GG.png
|
||||||
|
countryflags/GH.png
|
||||||
|
countryflags/GI.png
|
||||||
|
countryflags/GL.png
|
||||||
|
countryflags/GM.png
|
||||||
|
countryflags/GN.png
|
||||||
|
countryflags/GP.png
|
||||||
|
countryflags/GQ.png
|
||||||
|
countryflags/GR.png
|
||||||
|
countryflags/GS.png
|
||||||
|
countryflags/GT.png
|
||||||
|
countryflags/GU.png
|
||||||
|
countryflags/GW.png
|
||||||
|
countryflags/GY.png
|
||||||
|
countryflags/HK.png
|
||||||
|
countryflags/HN.png
|
||||||
|
countryflags/HR.png
|
||||||
|
countryflags/HT.png
|
||||||
|
countryflags/HU.png
|
||||||
|
countryflags/ID.png
|
||||||
|
countryflags/IE.png
|
||||||
|
countryflags/IL.png
|
||||||
|
countryflags/IM.png
|
||||||
|
countryflags/IN.png
|
||||||
|
countryflags/IO.png
|
||||||
|
countryflags/IQ.png
|
||||||
|
countryflags/IR.png
|
||||||
|
countryflags/IS.png
|
||||||
|
countryflags/IT.png
|
||||||
|
countryflags/JE.png
|
||||||
|
countryflags/JM.png
|
||||||
|
countryflags/JO.png
|
||||||
|
countryflags/JP.png
|
||||||
|
countryflags/KE.png
|
||||||
|
countryflags/KG.png
|
||||||
|
countryflags/KH.png
|
||||||
|
countryflags/KI.png
|
||||||
|
countryflags/KM.png
|
||||||
|
countryflags/KN.png
|
||||||
|
countryflags/KP.png
|
||||||
|
countryflags/KR.png
|
||||||
|
countryflags/KW.png
|
||||||
|
countryflags/KY.png
|
||||||
|
countryflags/KZ.png
|
||||||
|
countryflags/LA.png
|
||||||
|
countryflags/LB.png
|
||||||
|
countryflags/LC.png
|
||||||
|
countryflags/LI.png
|
||||||
|
countryflags/LK.png
|
||||||
|
countryflags/LR.png
|
||||||
|
countryflags/LS.png
|
||||||
|
countryflags/LT.png
|
||||||
|
countryflags/LU.png
|
||||||
|
countryflags/LV.png
|
||||||
|
countryflags/LY.png
|
||||||
|
countryflags/MA.png
|
||||||
|
countryflags/MC.png
|
||||||
|
countryflags/MD.png
|
||||||
|
countryflags/ME.png
|
||||||
|
countryflags/MF.png
|
||||||
|
countryflags/MG.png
|
||||||
|
countryflags/MH.png
|
||||||
|
countryflags/MK.png
|
||||||
|
countryflags/ML.png
|
||||||
|
countryflags/MM.png
|
||||||
|
countryflags/MN.png
|
||||||
|
countryflags/MO.png
|
||||||
|
countryflags/MP.png
|
||||||
|
countryflags/MQ.png
|
||||||
|
countryflags/MR.png
|
||||||
|
countryflags/MS.png
|
||||||
|
countryflags/MT.png
|
||||||
|
countryflags/MU.png
|
||||||
|
countryflags/MV.png
|
||||||
|
countryflags/MW.png
|
||||||
|
countryflags/MX.png
|
||||||
|
countryflags/MY.png
|
||||||
|
countryflags/MZ.png
|
||||||
|
countryflags/NA.png
|
||||||
|
countryflags/NC.png
|
||||||
|
countryflags/NE.png
|
||||||
|
countryflags/NF.png
|
||||||
|
countryflags/NG.png
|
||||||
|
countryflags/NI.png
|
||||||
|
countryflags/NL.png
|
||||||
|
countryflags/NO.png
|
||||||
|
countryflags/NP.png
|
||||||
|
countryflags/NR.png
|
||||||
|
countryflags/NU.png
|
||||||
|
countryflags/NZ.png
|
||||||
|
countryflags/OM.png
|
||||||
|
countryflags/PA.png
|
||||||
|
countryflags/PE.png
|
||||||
|
countryflags/PF.png
|
||||||
|
countryflags/PG.png
|
||||||
|
countryflags/PH.png
|
||||||
|
countryflags/PK.png
|
||||||
|
countryflags/PL.png
|
||||||
|
countryflags/PM.png
|
||||||
|
countryflags/PN.png
|
||||||
|
countryflags/PR.png
|
||||||
|
countryflags/PS.png
|
||||||
|
countryflags/PT.png
|
||||||
|
countryflags/PW.png
|
||||||
|
countryflags/PY.png
|
||||||
|
countryflags/QA.png
|
||||||
|
countryflags/RE.png
|
||||||
|
countryflags/RO.png
|
||||||
|
countryflags/RS.png
|
||||||
|
countryflags/RU.png
|
||||||
|
countryflags/RW.png
|
||||||
|
countryflags/SA.png
|
||||||
|
countryflags/SB.png
|
||||||
|
countryflags/SC.png
|
||||||
|
countryflags/SD.png
|
||||||
|
countryflags/SE.png
|
||||||
|
countryflags/SG.png
|
||||||
|
countryflags/SH.png
|
||||||
|
countryflags/SI.png
|
||||||
|
countryflags/SK.png
|
||||||
|
countryflags/SL.png
|
||||||
|
countryflags/SM.png
|
||||||
|
countryflags/SN.png
|
||||||
|
countryflags/SO.png
|
||||||
|
countryflags/SR.png
|
||||||
|
countryflags/SS.png
|
||||||
|
countryflags/ST.png
|
||||||
|
countryflags/SV.png
|
||||||
|
countryflags/SX.png
|
||||||
|
countryflags/SY.png
|
||||||
|
countryflags/SZ.png
|
||||||
|
countryflags/TC.png
|
||||||
|
countryflags/TD.png
|
||||||
|
countryflags/TF.png
|
||||||
|
countryflags/TG.png
|
||||||
|
countryflags/TH.png
|
||||||
|
countryflags/TJ.png
|
||||||
|
countryflags/TK.png
|
||||||
|
countryflags/TL.png
|
||||||
|
countryflags/TM.png
|
||||||
|
countryflags/TN.png
|
||||||
|
countryflags/TO.png
|
||||||
|
countryflags/TR.png
|
||||||
|
countryflags/TT.png
|
||||||
|
countryflags/TV.png
|
||||||
|
countryflags/TW.png
|
||||||
|
countryflags/TZ.png
|
||||||
|
countryflags/UA.png
|
||||||
|
countryflags/UG.png
|
||||||
|
countryflags/US.png
|
||||||
|
countryflags/UY.png
|
||||||
|
countryflags/UZ.png
|
||||||
|
countryflags/VA.png
|
||||||
|
countryflags/VC.png
|
||||||
|
countryflags/VE.png
|
||||||
|
countryflags/VG.png
|
||||||
|
countryflags/VI.png
|
||||||
|
countryflags/VN.png
|
||||||
|
countryflags/VU.png
|
||||||
|
countryflags/WF.png
|
||||||
|
countryflags/WS.png
|
||||||
|
countryflags/XCA.png
|
||||||
|
countryflags/XEN.png
|
||||||
|
countryflags/XEU.png
|
||||||
|
countryflags/XNI.png
|
||||||
|
countryflags/XSC.png
|
||||||
|
countryflags/XWA.png
|
||||||
|
countryflags/YE.png
|
||||||
|
countryflags/ZA.png
|
||||||
|
countryflags/ZM.png
|
||||||
|
countryflags/ZW.png
|
||||||
|
countryflags/default.png
|
||||||
|
countryflags/index.txt
|
||||||
|
debug_font.png
|
||||||
|
demo_buttons.png
|
||||||
|
demo_buttons2.png
|
||||||
|
editor/audio_source.png
|
||||||
|
editor/background.png
|
||||||
|
editor/basic_freeze.rules
|
||||||
|
editor/checker.png
|
||||||
|
editor/cursor.png
|
||||||
|
editor/ddmax_freeze.rules
|
||||||
|
editor/ddnet_tiles.rules
|
||||||
|
editor/ddnet_walls.rules
|
||||||
|
editor/desert_main.rules
|
||||||
|
editor/entities/DDNet.png
|
||||||
|
editor/entities/FNG.png
|
||||||
|
editor/entities/Race.png
|
||||||
|
editor/entities/Vanilla.png
|
||||||
|
editor/entities/blockworlds.png
|
||||||
|
editor/entities_clear/blockworlds.png
|
||||||
|
editor/entities_clear/ddnet.png
|
||||||
|
editor/entities_clear/ddrace.png
|
||||||
|
editor/entities_clear/fng.png
|
||||||
|
editor/entities_clear/race.png
|
||||||
|
editor/entities_clear/vanilla.png
|
||||||
|
editor/fadeout.rules
|
||||||
|
editor/front.png
|
||||||
|
editor/generic_clear.rules
|
||||||
|
editor/generic_unhookable.rules
|
||||||
|
editor/generic_unhookable_0.7.rules
|
||||||
|
editor/grass_main.rules
|
||||||
|
editor/grass_main_0.7.rules
|
||||||
|
editor/jungle_main.rules
|
||||||
|
editor/jungle_midground.rules
|
||||||
|
editor/round_tiles.rules
|
||||||
|
editor/speed_arrow.png
|
||||||
|
editor/speedup.png
|
||||||
|
editor/switch.png
|
||||||
|
editor/tele.png
|
||||||
|
editor/tune.png
|
||||||
|
editor/water.rules
|
||||||
|
editor/winter_main.rules
|
||||||
|
emoticons.png
|
||||||
|
file_icons.png
|
||||||
|
fonts/DejaVuSansCJKName.ttf
|
||||||
|
fonts/DejavuWenQuanYiMicroHei.ttf
|
||||||
|
fonts/Icons.ttf
|
||||||
|
game.png
|
||||||
|
gui_buttons.png
|
||||||
|
gui_cursor.png
|
||||||
|
gui_icons.png
|
||||||
|
gui_logo.png
|
||||||
|
languages/belarusian.txt
|
||||||
|
languages/bosnian.txt
|
||||||
|
languages/brazilian_portuguese.txt
|
||||||
|
languages/bulgarian.txt
|
||||||
|
languages/catalan.txt
|
||||||
|
languages/chuvash.txt
|
||||||
|
languages/czech.txt
|
||||||
|
languages/danish.txt
|
||||||
|
languages/dutch.txt
|
||||||
|
languages/finnish.txt
|
||||||
|
languages/french.txt
|
||||||
|
languages/german.txt
|
||||||
|
languages/greek.txt
|
||||||
|
languages/hungarian.txt
|
||||||
|
languages/index.txt
|
||||||
|
languages/italian.txt
|
||||||
|
languages/japanese.txt
|
||||||
|
languages/korean.txt
|
||||||
|
languages/kyrgyz.txt
|
||||||
|
languages/license.txt
|
||||||
|
languages/norwegian.txt
|
||||||
|
languages/persian.txt
|
||||||
|
languages/polish.txt
|
||||||
|
languages/portuguese.txt
|
||||||
|
languages/romanian.txt
|
||||||
|
languages/russian.txt
|
||||||
|
languages/serbian.txt
|
||||||
|
languages/simplified_chinese.txt
|
||||||
|
languages/slovak.txt
|
||||||
|
languages/spanish.txt
|
||||||
|
languages/swedish.txt
|
||||||
|
languages/traditional_chinese.txt
|
||||||
|
languages/turkish.txt
|
||||||
|
languages/ukrainian.txt
|
||||||
|
mapres/basic_freeze.png
|
||||||
|
mapres/bg_cloud1.png
|
||||||
|
mapres/bg_cloud2.png
|
||||||
|
mapres/bg_cloud3.png
|
||||||
|
mapres/ddmax_freeze.png
|
||||||
|
mapres/ddnet_start.png
|
||||||
|
mapres/ddnet_tiles.png
|
||||||
|
mapres/ddnet_walls.png
|
||||||
|
mapres/desert_background.png
|
||||||
|
mapres/desert_doodads.png
|
||||||
|
mapres/desert_main.png
|
||||||
|
mapres/desert_mountains.png
|
||||||
|
mapres/desert_mountains2.png
|
||||||
|
mapres/desert_mountains_new_background.png
|
||||||
|
mapres/desert_mountains_new_foreground.png
|
||||||
|
mapres/desert_sun.png
|
||||||
|
mapres/entities.png
|
||||||
|
mapres/fadeout.png
|
||||||
|
mapres/font_teeworlds.png
|
||||||
|
mapres/font_teeworlds_alt.png
|
||||||
|
mapres/generic_clear.png
|
||||||
|
mapres/generic_deathtiles.png
|
||||||
|
mapres/generic_lamps.png
|
||||||
|
mapres/generic_unhookable.png
|
||||||
|
mapres/generic_unhookable_0.7.png
|
||||||
|
mapres/grass_doodads.png
|
||||||
|
mapres/grass_doodads_0.7.png
|
||||||
|
mapres/grass_main.png
|
||||||
|
mapres/grass_main_0.7.png
|
||||||
|
mapres/jungle_background.png
|
||||||
|
mapres/jungle_deathtiles.png
|
||||||
|
mapres/jungle_doodads.png
|
||||||
|
mapres/jungle_main.png
|
||||||
|
mapres/jungle_midground.png
|
||||||
|
mapres/jungle_unhookables.png
|
||||||
|
mapres/light.png
|
||||||
|
mapres/mixed_tiles.png
|
||||||
|
mapres/moon.png
|
||||||
|
mapres/mountains.png
|
||||||
|
mapres/round_tiles.png
|
||||||
|
mapres/snow.png
|
||||||
|
mapres/snow_mountain.png
|
||||||
|
mapres/stars.png
|
||||||
|
mapres/sun.png
|
||||||
|
mapres/water.png
|
||||||
|
mapres/winter_doodads.png
|
||||||
|
mapres/winter_main.png
|
||||||
|
mapres/winter_mountains.png
|
||||||
|
mapres/winter_mountains2.png
|
||||||
|
mapres/winter_mountains3.png
|
||||||
|
maps/Goo!.map
|
||||||
|
maps/Kobra\ 4.map
|
||||||
|
maps/ctf1.map
|
||||||
|
maps/ctf2.map
|
||||||
|
maps/ctf3.map
|
||||||
|
maps/ctf4.map
|
||||||
|
maps/ctf5.map
|
||||||
|
maps/ctf6.map
|
||||||
|
maps/ctf7.map
|
||||||
|
maps/dm1.map
|
||||||
|
maps/dm2.map
|
||||||
|
maps/dm6.map
|
||||||
|
maps/dm7.map
|
||||||
|
maps/dm8.map
|
||||||
|
maps/dm9.map
|
||||||
|
particles.png
|
||||||
|
shader/bordertile.frag
|
||||||
|
shader/bordertile.vert
|
||||||
|
shader/bordertileline.frag
|
||||||
|
shader/bordertileline.vert
|
||||||
|
shader/bordertilelinetex.frag
|
||||||
|
shader/bordertilelinetex.vert
|
||||||
|
shader/bordertiletex.frag
|
||||||
|
shader/bordertiletex.vert
|
||||||
|
shader/prim.frag
|
||||||
|
shader/prim.vert
|
||||||
|
shader/quad.frag
|
||||||
|
shader/quad.vert
|
||||||
|
shader/quadtex.frag
|
||||||
|
shader/quadtex.vert
|
||||||
|
shader/sprite.frag
|
||||||
|
shader/sprite.vert
|
||||||
|
shader/spritemulti.frag
|
||||||
|
shader/spritemulti.vert
|
||||||
|
shader/text.frag
|
||||||
|
shader/text.vert
|
||||||
|
shader/tile.frag
|
||||||
|
shader/tile.vert
|
||||||
|
shader/tiletex.frag
|
||||||
|
shader/tiletex.vert
|
||||||
|
skins/Ablush\ NeoN.png
|
||||||
|
skins/Aoe4leg.png
|
||||||
|
skins/Apish\ Coke.png
|
||||||
|
skins/BadAnqelMonster.png
|
||||||
|
skins/Black\ Phantom\ heinrich5991.png
|
||||||
|
skins/Blind\ r0xr.png
|
||||||
|
skins/DuMoH.png
|
||||||
|
skins/Evil\ Puffi.png
|
||||||
|
skins/Flying\ Silex.png
|
||||||
|
skins/Hidden\ Assassin.png
|
||||||
|
skins/Irradiated\ Sunny.png
|
||||||
|
skins/Mobys\ Skull.png
|
||||||
|
skins/PaladiN.png
|
||||||
|
skins/Red\ Coke.png
|
||||||
|
skins/Shadow.png
|
||||||
|
skins/Sonic.png
|
||||||
|
skins/Straw\ Crytek.png
|
||||||
|
skins/Terrorist.png
|
||||||
|
skins/Volt.png
|
||||||
|
skins/antiantey.png
|
||||||
|
skins/aqua.png
|
||||||
|
skins/atlas_by_whis.png
|
||||||
|
skins/bauer.png
|
||||||
|
skins/beast.png
|
||||||
|
skins/blacktee.png
|
||||||
|
skins/bluekitty.png
|
||||||
|
skins/bluestripe.png
|
||||||
|
skins/bomb.png
|
||||||
|
skins/brownbear.png
|
||||||
|
skins/bunny.png
|
||||||
|
skins/caesar.png
|
||||||
|
skins/cammo.png
|
||||||
|
skins/cammostripes.png
|
||||||
|
skins/chera.png
|
||||||
|
skins/chinese_by_whis.png
|
||||||
|
skins/clefairy.png
|
||||||
|
skins/coala.png
|
||||||
|
skins/coala_bluekitty.png
|
||||||
|
skins/coala_bluestripe.png
|
||||||
|
skins/coala_cammo.png
|
||||||
|
skins/coala_cammostripes.png
|
||||||
|
skins/coala_default.png
|
||||||
|
skins/coala_limekitty.png
|
||||||
|
skins/coala_pinky.png
|
||||||
|
skins/coala_redbopp.png
|
||||||
|
skins/coala_redstripe.png
|
||||||
|
skins/coala_saddo.png
|
||||||
|
skins/coala_toptri.png
|
||||||
|
skins/coala_twinbop.png
|
||||||
|
skins/coala_twintri.png
|
||||||
|
skins/coala_warpaint.png
|
||||||
|
skins/coala_x_ninja.png
|
||||||
|
skins/default.png
|
||||||
|
skins/demonlimekitty.png
|
||||||
|
skins/dino.png
|
||||||
|
skins/dragon.png
|
||||||
|
skins/draw.png
|
||||||
|
skins/emo.png
|
||||||
|
skins/evil.png
|
||||||
|
skins/evilwolfe.png
|
||||||
|
skins/fuzzy_coala.png
|
||||||
|
skins/ghost.png
|
||||||
|
skins/ghostjtj.png
|
||||||
|
skins/giraffe.png
|
||||||
|
skins/greensward.png
|
||||||
|
skins/greyfox.png
|
||||||
|
skins/greyfox_2.png
|
||||||
|
skins/hammie-chew.png
|
||||||
|
skins/hammie-whis.png
|
||||||
|
skins/hedgehog.png
|
||||||
|
skins/jeet.png
|
||||||
|
skins/kintaro_2.png
|
||||||
|
skins/kirby.png
|
||||||
|
skins/kitty_bluestripe.png
|
||||||
|
skins/kitty_brownbear.png
|
||||||
|
skins/kitty_cammo.png
|
||||||
|
skins/kitty_cammostripes.png
|
||||||
|
skins/kitty_coala.png
|
||||||
|
skins/kitty_default.png
|
||||||
|
skins/kitty_pinky.png
|
||||||
|
skins/kitty_redbopp.png
|
||||||
|
skins/kitty_redstripe.png
|
||||||
|
skins/kitty_saddo.png
|
||||||
|
skins/kitty_toptri.png
|
||||||
|
skins/kitty_twinbop.png
|
||||||
|
skins/kitty_twintri.png
|
||||||
|
skins/kitty_warpaint.png
|
||||||
|
skins/kitty_x_ninja.png
|
||||||
|
skins/lightbulb.png
|
||||||
|
skins/limekitty.png
|
||||||
|
skins/m&mred.png
|
||||||
|
skins/m&myellow.png
|
||||||
|
skins/masterchief.png
|
||||||
|
skins/mermydon-coala.png
|
||||||
|
skins/mermydon.png
|
||||||
|
skins/mike.png
|
||||||
|
skins/monstee.png
|
||||||
|
skins/mouse.png
|
||||||
|
skins/musmann.png
|
||||||
|
skins/nanami.png
|
||||||
|
skins/nanas.png
|
||||||
|
skins/napoleon.png
|
||||||
|
skins/nersif.png
|
||||||
|
skins/nosey.png
|
||||||
|
skins/oldman.png
|
||||||
|
skins/oldschool.png
|
||||||
|
skins/pbody_by_whis.png
|
||||||
|
skins/penguin.png
|
||||||
|
skins/pepsi.png
|
||||||
|
skins/pikminpurple.png
|
||||||
|
skins/pikminwhite.png
|
||||||
|
skins/pikminyellow.png
|
||||||
|
skins/pinky.png
|
||||||
|
skins/random.png
|
||||||
|
skins/red_bird.png
|
||||||
|
skins/redbopp.png
|
||||||
|
skins/redstripe.png
|
||||||
|
skins/roman.png
|
||||||
|
skins/saddo.png
|
||||||
|
skins/santa_bluekitty.png
|
||||||
|
skins/santa_bluestripe.png
|
||||||
|
skins/santa_brownbear.png
|
||||||
|
skins/santa_cammo.png
|
||||||
|
skins/santa_cammostripes.png
|
||||||
|
skins/santa_coala.png
|
||||||
|
skins/santa_default.png
|
||||||
|
skins/santa_limekitty.png
|
||||||
|
skins/santa_pinky.png
|
||||||
|
skins/santa_redbopp.png
|
||||||
|
skins/santa_redstripe.png
|
||||||
|
skins/santa_saddo.png
|
||||||
|
skins/santa_toptri.png
|
||||||
|
skins/santa_twinbop.png
|
||||||
|
skins/santa_twintri.png
|
||||||
|
skins/santa_warpaint.png
|
||||||
|
skins/savage.png
|
||||||
|
skins/t2.png
|
||||||
|
skins/tails.png
|
||||||
|
skins/tank.png
|
||||||
|
skins/tauren.png
|
||||||
|
skins/teerasta.png
|
||||||
|
skins/teledipsy.png
|
||||||
|
skins/telelaalaa.png
|
||||||
|
skins/telepo.png
|
||||||
|
skins/teletinkywinky.png
|
||||||
|
skins/toptri.png
|
||||||
|
skins/troll.png
|
||||||
|
skins/ts2_contest_skin.png
|
||||||
|
skins/tweety.png
|
||||||
|
skins/twinbop.png
|
||||||
|
skins/twintri.png
|
||||||
|
skins/veteran.png
|
||||||
|
skins/voodoo_tee.png
|
||||||
|
skins/warpaint.png
|
||||||
|
skins/wartee.png
|
||||||
|
skins/whis.png
|
||||||
|
skins/x_ninja.png
|
||||||
|
wordlist.txt
|
||||||
|
)
|
||||||
|
|
||||||
|
set_glob(DATA GLOB_RECURSE "frag;json;map;pem;png;rules;ttf;txt;vert;wv" data ${EXPECTED_DATA})
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# COPY DATA AND DLLS
|
# COPY DATA AND DLLS
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
file(COPY data DESTINATION .)
|
foreach(datafile ${DATA})
|
||||||
|
file(RELATIVE_PATH OUT ${PROJECT_SOURCE_DIR}/data ${datafile})
|
||||||
|
get_filename_component(DESTINATION data/${OUT} PATH)
|
||||||
|
file(MAKE_DIRECTORY ${DESTINATION})
|
||||||
|
file(COPY ${datafile} DESTINATION ${DESTINATION})
|
||||||
|
endforeach()
|
||||||
set(COPY_FILES
|
set(COPY_FILES
|
||||||
${CURL_COPY_FILES}
|
${CURL_COPY_FILES}
|
||||||
${FREETYPE_COPY_FILES}
|
${FREETYPE_COPY_FILES}
|
||||||
|
|
|
@ -65,7 +65,7 @@ void CGraphicsBackend_Threaded::ThreadFunc(void *pUser)
|
||||||
}
|
}
|
||||||
#if defined(CONF_VIDEORECORDER)
|
#if defined(CONF_VIDEORECORDER)
|
||||||
if (IVideo::Current())
|
if (IVideo::Current())
|
||||||
IVideo::Current()->nextVideoFrame_thread();
|
IVideo::Current()->NextVideoFrameThread();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2547,10 +2547,10 @@ void CClient::Update()
|
||||||
#if defined(CONF_VIDEORECORDER)
|
#if defined(CONF_VIDEORECORDER)
|
||||||
if (m_DemoPlayer.IsPlaying() && IVideo::Current())
|
if (m_DemoPlayer.IsPlaying() && IVideo::Current())
|
||||||
{
|
{
|
||||||
if (IVideo::Current()->frameRendered())
|
if (IVideo::Current()->FrameRendered())
|
||||||
IVideo::Current()->nextVideoFrame();
|
IVideo::Current()->NextVideoFrame();
|
||||||
if (IVideo::Current()->aframeRendered())
|
if (IVideo::Current()->AudioFrameRendered())
|
||||||
IVideo::Current()->nextAudioFrame_timeline();
|
IVideo::Current()->NextAudioFrameTimeline();
|
||||||
}
|
}
|
||||||
else if(m_ButtonRender)
|
else if(m_ButtonRender)
|
||||||
Disconnect();
|
Disconnect();
|
||||||
|
@ -3371,10 +3371,10 @@ void CClient::Con_StartVideo(IConsole::IResult *pResult, void *pUserData)
|
||||||
if (!IVideo::Current())
|
if (!IVideo::Current())
|
||||||
{
|
{
|
||||||
new CVideo((CGraphics_Threaded*)pSelf->m_pGraphics, pSelf->Storage(), pSelf->m_pConsole, pSelf->Graphics()->ScreenWidth(), pSelf->Graphics()->ScreenHeight(), "");
|
new CVideo((CGraphics_Threaded*)pSelf->m_pGraphics, pSelf->Storage(), pSelf->m_pConsole, pSelf->Graphics()->ScreenWidth(), pSelf->Graphics()->ScreenHeight(), "");
|
||||||
IVideo::Current()->start();
|
IVideo::Current()->Start();
|
||||||
bool paused = pSelf->m_DemoPlayer.Info()->m_Info.m_Paused;
|
bool paused = pSelf->m_DemoPlayer.Info()->m_Info.m_Paused;
|
||||||
if(paused)
|
if(paused)
|
||||||
IVideo::Current()->pause(true);
|
IVideo::Current()->Pause(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pSelf->m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "videorecorder", "Videorecorder already running.");
|
pSelf->m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "videorecorder", "Videorecorder already running.");
|
||||||
|
@ -3391,7 +3391,7 @@ void CClient::StartVideo(IConsole::IResult *pResult, void *pUserData, const char
|
||||||
if (!IVideo::Current())
|
if (!IVideo::Current())
|
||||||
{
|
{
|
||||||
new CVideo((CGraphics_Threaded*)pSelf->m_pGraphics, pSelf->Storage(), pSelf->m_pConsole, pSelf->Graphics()->ScreenWidth(), pSelf->Graphics()->ScreenHeight(), pVideoName);
|
new CVideo((CGraphics_Threaded*)pSelf->m_pGraphics, pSelf->Storage(), pSelf->m_pConsole, pSelf->Graphics()->ScreenWidth(), pSelf->Graphics()->ScreenHeight(), pVideoName);
|
||||||
IVideo::Current()->start();
|
IVideo::Current()->Start();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pSelf->m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "videorecorder", "Videorecorder already running.");
|
pSelf->m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "videorecorder", "Videorecorder already running.");
|
||||||
|
@ -3400,7 +3400,7 @@ void CClient::StartVideo(IConsole::IResult *pResult, void *pUserData, const char
|
||||||
void CClient::Con_StopVideo(IConsole::IResult *pResult, void *pUserData)
|
void CClient::Con_StopVideo(IConsole::IResult *pResult, void *pUserData)
|
||||||
{
|
{
|
||||||
if (IVideo::Current())
|
if (IVideo::Current())
|
||||||
IVideo::Current()->stop();
|
IVideo::Current()->Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,6 +21,10 @@
|
||||||
|
|
||||||
#include <math.h> // cosf, sinf, log2f
|
#include <math.h> // cosf, sinf, log2f
|
||||||
|
|
||||||
|
#if defined(CONF_VIDEORECORDER)
|
||||||
|
#include "video.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "graphics_threaded.h"
|
#include "graphics_threaded.h"
|
||||||
|
|
||||||
static CVideoMode g_aFakeModes[] = {
|
static CVideoMode g_aFakeModes[] = {
|
||||||
|
@ -2050,9 +2054,7 @@ int CGraphics_Threaded::IssueInit()
|
||||||
if(g_Config.m_GfxFullscreen) Flags |= IGraphicsBackend::INITFLAG_FULLSCREEN;
|
if(g_Config.m_GfxFullscreen) Flags |= IGraphicsBackend::INITFLAG_FULLSCREEN;
|
||||||
if(g_Config.m_GfxVsync) Flags |= IGraphicsBackend::INITFLAG_VSYNC;
|
if(g_Config.m_GfxVsync) Flags |= IGraphicsBackend::INITFLAG_VSYNC;
|
||||||
if(g_Config.m_GfxHighdpi) Flags |= IGraphicsBackend::INITFLAG_HIGHDPI;
|
if(g_Config.m_GfxHighdpi) Flags |= IGraphicsBackend::INITFLAG_HIGHDPI;
|
||||||
#ifndef CONF_VIDEORECORDER
|
|
||||||
if(g_Config.m_GfxResizable) Flags |= IGraphicsBackend::INITFLAG_RESIZABLE;
|
if(g_Config.m_GfxResizable) Flags |= IGraphicsBackend::INITFLAG_RESIZABLE;
|
||||||
#endif
|
|
||||||
|
|
||||||
int r = m_pBackend->Init("DDNet Client", &g_Config.m_GfxScreen, &g_Config.m_GfxScreenWidth, &g_Config.m_GfxScreenHeight, g_Config.m_GfxFsaaSamples, Flags, &m_DesktopScreenWidth, &m_DesktopScreenHeight, &m_ScreenWidth, &m_ScreenHeight, m_pStorage);
|
int r = m_pBackend->Init("DDNet Client", &g_Config.m_GfxScreen, &g_Config.m_GfxScreenWidth, &g_Config.m_GfxScreenHeight, g_Config.m_GfxFsaaSamples, Flags, &m_DesktopScreenWidth, &m_DesktopScreenHeight, &m_ScreenWidth, &m_ScreenHeight, m_pStorage);
|
||||||
m_UseOpenGL3_3 = m_pBackend->IsOpenGL3_3();
|
m_UseOpenGL3_3 = m_pBackend->IsOpenGL3_3();
|
||||||
|
@ -2186,6 +2188,11 @@ bool CGraphics_Threaded::SetWindowScreen(int Index)
|
||||||
|
|
||||||
void CGraphics_Threaded::Resize(int w, int h)
|
void CGraphics_Threaded::Resize(int w, int h)
|
||||||
{
|
{
|
||||||
|
#if defined(CONF_VIDEORECORDER)
|
||||||
|
if (IVideo::Current() && IVideo::Current()->IsRecording())
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
if(m_ScreenWidth == w && m_ScreenHeight == h)
|
if(m_ScreenWidth == w && m_ScreenHeight == h)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -281,7 +281,7 @@ int CInput::Update()
|
||||||
switch (Event.window.event)
|
switch (Event.window.event)
|
||||||
{
|
{
|
||||||
case SDL_WINDOWEVENT_RESIZED:
|
case SDL_WINDOWEVENT_RESIZED:
|
||||||
#if defined(SDL_VIDEO_DRIVER_X11) && !defined(CONF_VIDEORECORDER)
|
#if defined(SDL_VIDEO_DRIVER_X11)
|
||||||
Graphics()->Resize(Event.window.data1, Event.window.data2);
|
Graphics()->Resize(Event.window.data1, Event.window.data2);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -288,7 +288,7 @@ static void SdlCallback(void *pUnused, Uint8 *pStream, int Len)
|
||||||
if (!(IVideo::Current() && g_Config.m_ClVideoSndEnable))
|
if (!(IVideo::Current() && g_Config.m_ClVideoSndEnable))
|
||||||
Mix((short *)pStream, Len/2/2);
|
Mix((short *)pStream, Len/2/2);
|
||||||
else
|
else
|
||||||
IVideo::Current()->nextAudioFrame(Mix);
|
IVideo::Current()->NextAudioFrame(Mix);
|
||||||
#else
|
#else
|
||||||
Mix((short *)pStream, Len/2/2);
|
Mix((short *)pStream, Len/2/2);
|
||||||
#endif
|
#endif
|
||||||
|
@ -361,7 +361,7 @@ int CSound::Update()
|
||||||
}
|
}
|
||||||
//#if defined(CONF_VIDEORECORDER)
|
//#if defined(CONF_VIDEORECORDER)
|
||||||
// if(IVideo::Current() && g_Config.m_ClVideoSndEnable)
|
// if(IVideo::Current() && g_Config.m_ClVideoSndEnable)
|
||||||
// IVideo::Current()->nextAudioFrame(Mix);
|
// IVideo::Current()->NextAudioFrame(Mix);
|
||||||
//#endif
|
//#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,10 @@
|
||||||
|
|
||||||
#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */
|
#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */
|
||||||
|
|
||||||
const size_t format_nchannels = 3;
|
const size_t FORMAT_NCHANNELS = 3;
|
||||||
static LOCK m_WriteLock = 0;
|
static LOCK g_WriteLock = 0;
|
||||||
|
|
||||||
CVideo::CVideo(CGraphics_Threaded* pGraphics, IStorage* pStorage, IConsole *pConsole, int width, int height, const char *name) :
|
CVideo::CVideo(CGraphics_Threaded* pGraphics, IStorage* pStorage, IConsole *pConsole, int Width, int Height, const char *pName) :
|
||||||
m_pGraphics(pGraphics),
|
m_pGraphics(pGraphics),
|
||||||
m_pStorage(pStorage),
|
m_pStorage(pStorage),
|
||||||
m_pConsole(pConsole),
|
m_pConsole(pConsole),
|
||||||
|
@ -30,9 +30,9 @@ CVideo::CVideo(CGraphics_Threaded* pGraphics, IStorage* pStorage, IConsole *pCon
|
||||||
m_VideoCodec = 0;
|
m_VideoCodec = 0;
|
||||||
m_AudioCodec = 0;
|
m_AudioCodec = 0;
|
||||||
|
|
||||||
m_Width = width;
|
m_Width = Width;
|
||||||
m_Height = height;
|
m_Height = Height;
|
||||||
str_copy(m_Name, name, sizeof(m_Name));
|
str_copy(m_Name, pName, sizeof(m_Name));
|
||||||
|
|
||||||
m_FPS = g_Config.m_ClVideoRecorderFPS;
|
m_FPS = g_Config.m_ClVideoRecorderFPS;
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ CVideo::CVideo(CGraphics_Threaded* pGraphics, IStorage* pStorage, IConsole *pCon
|
||||||
m_ProcessingAudioFrame = false;
|
m_ProcessingAudioFrame = false;
|
||||||
|
|
||||||
m_NextFrame = false;
|
m_NextFrame = false;
|
||||||
m_NextaFrame = false;
|
m_NextAudioFrame = false;
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
m_HasAudio = g_Config.m_ClVideoSndEnable;
|
m_HasAudio = g_Config.m_ClVideoSndEnable;
|
||||||
|
@ -53,21 +53,21 @@ CVideo::CVideo(CGraphics_Threaded* pGraphics, IStorage* pStorage, IConsole *pCon
|
||||||
|
|
||||||
ms_TickTime = time_freq() / m_FPS;
|
ms_TickTime = time_freq() / m_FPS;
|
||||||
ms_pCurrentVideo = this;
|
ms_pCurrentVideo = this;
|
||||||
m_WriteLock = lock_create();
|
g_WriteLock = lock_create();
|
||||||
}
|
}
|
||||||
|
|
||||||
CVideo::~CVideo()
|
CVideo::~CVideo()
|
||||||
{
|
{
|
||||||
ms_pCurrentVideo = 0;
|
ms_pCurrentVideo = 0;
|
||||||
lock_destroy(m_WriteLock);
|
lock_destroy(g_WriteLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVideo::start()
|
void CVideo::Start()
|
||||||
{
|
{
|
||||||
char aDate[20];
|
char aDate[20];
|
||||||
str_timestamp(aDate, sizeof(aDate));
|
str_timestamp(aDate, sizeof(aDate));
|
||||||
char aBuf[256];
|
char aBuf[256];
|
||||||
if (strlen(m_Name) != 0)
|
if(strlen(m_Name) != 0)
|
||||||
str_format(aBuf, sizeof(aBuf), "videos/%s", m_Name);
|
str_format(aBuf, sizeof(aBuf), "videos/%s", m_Name);
|
||||||
else
|
else
|
||||||
str_format(aBuf, sizeof(aBuf), "videos/%s.mp4", aDate);
|
str_format(aBuf, sizeof(aBuf), "videos/%s.mp4", aDate);
|
||||||
|
@ -86,7 +86,7 @@ void CVideo::start()
|
||||||
}
|
}
|
||||||
avformat_alloc_output_context2(&m_pFormatContext, 0, "mp4", aWholePath);
|
avformat_alloc_output_context2(&m_pFormatContext, 0, "mp4", aWholePath);
|
||||||
|
|
||||||
if (!m_pFormatContext)
|
if(!m_pFormatContext)
|
||||||
{
|
{
|
||||||
dbg_msg("video_recorder", "Failed to create formatcontext for recoding video.");
|
dbg_msg("video_recorder", "Failed to create formatcontext for recoding video.");
|
||||||
return;
|
return;
|
||||||
|
@ -94,25 +94,25 @@ void CVideo::start()
|
||||||
|
|
||||||
m_pFormat = m_pFormatContext->oformat;
|
m_pFormat = m_pFormatContext->oformat;
|
||||||
|
|
||||||
size_t nvals = format_nchannels * m_Width * m_Height;
|
size_t NVals = FORMAT_NCHANNELS * m_Width * m_Height;
|
||||||
m_pPixels = (uint8_t *)malloc(nvals * sizeof(GLubyte));
|
m_pPixels = (uint8_t *)malloc(NVals * sizeof(GLubyte));
|
||||||
m_pRGB = (uint8_t *)malloc(nvals * sizeof(uint8_t));
|
m_pRGB = (uint8_t *)malloc(NVals * sizeof(uint8_t));
|
||||||
|
|
||||||
|
|
||||||
/* Add the audio and video streams using the default format codecs
|
/* Add the audio and video streams using the default format codecs
|
||||||
* and initialize the codecs. */
|
* and initialize the codecs. */
|
||||||
if (m_pFormat->video_codec != AV_CODEC_ID_NONE)
|
if(m_pFormat->video_codec != AV_CODEC_ID_NONE)
|
||||||
{
|
{
|
||||||
add_stream(&m_VideoStream, m_pFormatContext, &m_VideoCodec, m_pFormat->video_codec);
|
AddStream(&m_VideoStream, m_pFormatContext, &m_VideoCodec, m_pFormat->video_codec);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dbg_msg("video_recorder", "Failed to add VideoStream for recoding video.");
|
dbg_msg("video_recorder", "Failed to add VideoStream for recoding video.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_HasAudio && m_pFormat->audio_codec != AV_CODEC_ID_NONE)
|
if(m_HasAudio && m_pFormat->audio_codec != AV_CODEC_ID_NONE)
|
||||||
{
|
{
|
||||||
add_stream(&m_AudioStream, m_pFormatContext, &m_AudioCodec, m_pFormat->audio_codec);
|
AddStream(&m_AudioStream, m_pFormatContext, &m_AudioCodec, m_pFormat->audio_codec);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -121,113 +121,113 @@ void CVideo::start()
|
||||||
|
|
||||||
/* Now that all the parameters are set, we can open the audio and
|
/* Now that all the parameters are set, we can open the audio and
|
||||||
* video codecs and allocate the necessary encode buffers. */
|
* video codecs and allocate the necessary encode buffers. */
|
||||||
open_video();
|
OpenVideo();
|
||||||
|
|
||||||
if (m_HasAudio)
|
if(m_HasAudio)
|
||||||
open_audio();
|
OpenAudio();
|
||||||
|
|
||||||
// TODO: remove/comment:
|
// TODO: remove/comment:
|
||||||
av_dump_format(m_pFormatContext, 0, aWholePath, 1);
|
av_dump_format(m_pFormatContext, 0, aWholePath, 1);
|
||||||
|
|
||||||
/* open the output file, if needed */
|
/* open the output file, if needed */
|
||||||
if (!(m_pFormat->flags & AVFMT_NOFILE))
|
if(!(m_pFormat->flags & AVFMT_NOFILE))
|
||||||
{
|
{
|
||||||
int ret = avio_open(&m_pFormatContext->pb, aWholePath, AVIO_FLAG_WRITE);
|
int Ret = avio_open(&m_pFormatContext->pb, aWholePath, AVIO_FLAG_WRITE);
|
||||||
if (ret < 0)
|
if(Ret < 0)
|
||||||
{
|
{
|
||||||
char aBuf[AV_ERROR_MAX_STRING_SIZE];
|
char aBuf[AV_ERROR_MAX_STRING_SIZE];
|
||||||
av_strerror(ret, aBuf, sizeof(aBuf));
|
av_strerror(Ret, aBuf, sizeof(aBuf));
|
||||||
dbg_msg("video_recorder", "Could not open '%s': %s", aWholePath, aBuf);
|
dbg_msg("video_recorder", "Could not open '%s': %s", aWholePath, aBuf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_VideoStream.sws_ctx)
|
if(!m_VideoStream.pSwsCtx)
|
||||||
{
|
{
|
||||||
m_VideoStream.sws_ctx = sws_getCachedContext(
|
m_VideoStream.pSwsCtx = sws_getCachedContext(
|
||||||
m_VideoStream.sws_ctx,
|
m_VideoStream.pSwsCtx,
|
||||||
m_VideoStream.enc->width, m_VideoStream.enc->height, AV_PIX_FMT_RGB24,
|
m_VideoStream.pEnc->width, m_VideoStream.pEnc->height, AV_PIX_FMT_RGB24,
|
||||||
m_VideoStream.enc->width, m_VideoStream.enc->height, AV_PIX_FMT_YUV420P,
|
m_VideoStream.pEnc->width, m_VideoStream.pEnc->height, AV_PIX_FMT_YUV420P,
|
||||||
0, 0, 0, 0
|
0, 0, 0, 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the stream header, if any. */
|
/* Write the stream header, if any. */
|
||||||
int ret = avformat_write_header(m_pFormatContext, &m_pOptDict);
|
int Ret = avformat_write_header(m_pFormatContext, &m_pOptDict);
|
||||||
if (ret < 0)
|
if(Ret < 0)
|
||||||
{
|
{
|
||||||
char aBuf[AV_ERROR_MAX_STRING_SIZE];
|
char aBuf[AV_ERROR_MAX_STRING_SIZE];
|
||||||
av_strerror(ret, aBuf, sizeof(aBuf));
|
av_strerror(Ret, aBuf, sizeof(aBuf));
|
||||||
dbg_msg("video_recorder", "Error occurred when opening output file: %s", aBuf);
|
dbg_msg("video_recorder", "Error occurred when opening output file: %s", aBuf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_Recording = true;
|
m_Recording = true;
|
||||||
m_Started = true;
|
m_Started = true;
|
||||||
ms_Time = time_get();
|
ms_Time = time_get();
|
||||||
m_vframe = 0;
|
m_Vframe = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVideo::pause(bool p)
|
void CVideo::Pause(bool Pause)
|
||||||
{
|
{
|
||||||
if(ms_pCurrentVideo)
|
if(ms_pCurrentVideo)
|
||||||
m_Recording = !p;
|
m_Recording = !Pause;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVideo::stop()
|
void CVideo::Stop()
|
||||||
{
|
{
|
||||||
m_Recording = false;
|
m_Recording = false;
|
||||||
|
|
||||||
while (m_ProcessingVideoFrame || m_ProcessingAudioFrame)
|
while(m_ProcessingVideoFrame || m_ProcessingAudioFrame)
|
||||||
thread_sleep(10);
|
thread_sleep(10);
|
||||||
|
|
||||||
finish_frames(&m_VideoStream);
|
FinishFrames(&m_VideoStream);
|
||||||
|
|
||||||
if (m_HasAudio)
|
if(m_HasAudio)
|
||||||
finish_frames(&m_AudioStream);
|
FinishFrames(&m_AudioStream);
|
||||||
|
|
||||||
av_write_trailer(m_pFormatContext);
|
av_write_trailer(m_pFormatContext);
|
||||||
|
|
||||||
close_stream(&m_VideoStream);
|
CloseStream(&m_VideoStream);
|
||||||
|
|
||||||
if (m_HasAudio)
|
if(m_HasAudio)
|
||||||
close_stream(&m_AudioStream);
|
CloseStream(&m_AudioStream);
|
||||||
//fclose(m_dbgfile);
|
//fclose(m_dbgfile);
|
||||||
|
|
||||||
if (!(m_pFormat->flags & AVFMT_NOFILE))
|
if(!(m_pFormat->flags & AVFMT_NOFILE))
|
||||||
avio_closep(&m_pFormatContext->pb);
|
avio_closep(&m_pFormatContext->pb);
|
||||||
|
|
||||||
if (m_pFormatContext)
|
if(m_pFormatContext)
|
||||||
avformat_free_context(m_pFormatContext);
|
avformat_free_context(m_pFormatContext);
|
||||||
|
|
||||||
if (m_pRGB)
|
if(m_pRGB)
|
||||||
free(m_pRGB);
|
free(m_pRGB);
|
||||||
|
|
||||||
if (m_pPixels)
|
if(m_pPixels)
|
||||||
free(m_pPixels);
|
free(m_pPixels);
|
||||||
|
|
||||||
if (ms_pCurrentVideo)
|
if(ms_pCurrentVideo)
|
||||||
delete ms_pCurrentVideo;
|
delete ms_pCurrentVideo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVideo::nextVideoFrame_thread()
|
void CVideo::NextVideoFrameThread()
|
||||||
{
|
{
|
||||||
if (m_NextFrame && m_Recording)
|
if(m_NextFrame && m_Recording)
|
||||||
{
|
{
|
||||||
// #ifdef CONF_PLATFORM_MACOSX
|
// #ifdef CONF_PLATFORM_MACOSX
|
||||||
// CAutoreleasePool AutoreleasePool;
|
// CAutoreleasePool AutoreleasePool;
|
||||||
// #endif
|
// #endif
|
||||||
m_vseq += 1;
|
m_Vseq += 1;
|
||||||
if(m_vseq >= 2)
|
if(m_Vseq >= 2)
|
||||||
{
|
{
|
||||||
m_ProcessingVideoFrame = true;
|
m_ProcessingVideoFrame = true;
|
||||||
m_VideoStream.frame->pts = (int64_t)m_VideoStream.enc->frame_number;
|
m_VideoStream.pFrame->pts = (int64_t)m_VideoStream.pEnc->frame_number;
|
||||||
dbg_msg("video_recorder", "vframe: %d", m_VideoStream.enc->frame_number);
|
dbg_msg("video_recorder", "vframe: %d", m_VideoStream.pEnc->frame_number);
|
||||||
|
|
||||||
read_rgb_from_gl();
|
ReadRGBFromGL();
|
||||||
fill_video_frame();
|
FillVideoFrame();
|
||||||
lock_wait(m_WriteLock);
|
lock_wait(g_WriteLock);
|
||||||
write_frame(&m_VideoStream);
|
WriteFrame(&m_VideoStream);
|
||||||
lock_unlock(m_WriteLock);
|
lock_unlock(g_WriteLock);
|
||||||
m_ProcessingVideoFrame = false;
|
m_ProcessingVideoFrame = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,9 +237,9 @@ void CVideo::nextVideoFrame_thread()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVideo::nextVideoFrame()
|
void CVideo::NextVideoFrame()
|
||||||
{
|
{
|
||||||
if (m_Recording)
|
if(m_Recording)
|
||||||
{
|
{
|
||||||
// #ifdef CONF_PLATFORM_MACOSX
|
// #ifdef CONF_PLATFORM_MACOSX
|
||||||
// CAutoreleasePool AutoreleasePool;
|
// CAutoreleasePool AutoreleasePool;
|
||||||
|
@ -250,7 +250,7 @@ void CVideo::nextVideoFrame()
|
||||||
ms_Time += ms_TickTime;
|
ms_Time += ms_TickTime;
|
||||||
ms_LocalTime = (ms_Time-ms_LocalStartTime)/(float)time_freq();
|
ms_LocalTime = (ms_Time-ms_LocalStartTime)/(float)time_freq();
|
||||||
m_NextFrame = true;
|
m_NextFrame = true;
|
||||||
m_vframe += 1;
|
m_Vframe += 1;
|
||||||
|
|
||||||
// m_pGraphics->KickCommandBuffer();
|
// m_pGraphics->KickCommandBuffer();
|
||||||
//thread_sleep(500);
|
//thread_sleep(500);
|
||||||
|
@ -259,77 +259,77 @@ void CVideo::nextVideoFrame()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVideo::nextAudioFrame_timeline()
|
void CVideo::NextAudioFrameTimeline()
|
||||||
{
|
{
|
||||||
if (m_Recording && m_HasAudio)
|
if(m_Recording && m_HasAudio)
|
||||||
{
|
{
|
||||||
//if (m_vframe * m_AudioStream.enc->sample_rate / m_FPS >= m_AudioStream.enc->frame_number*m_AudioStream.enc->frame_size)
|
//if(m_Vframe * m_AudioStream.pEnc->sample_rate / m_FPS >= m_AudioStream.pEnc->frame_number*m_AudioStream.pEnc->frame_size)
|
||||||
if (m_VideoStream.enc->frame_number * (double)m_AudioStream.enc->sample_rate / m_FPS >= (double)m_AudioStream.enc->frame_number*m_AudioStream.enc->frame_size)
|
if(m_VideoStream.pEnc->frame_number * (double)m_AudioStream.pEnc->sample_rate / m_FPS >= (double)m_AudioStream.pEnc->frame_number*m_AudioStream.pEnc->frame_size)
|
||||||
{
|
{
|
||||||
m_NextaFrame = true;
|
m_NextAudioFrame = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVideo::nextAudioFrame(void (*Mix)(short *pFinalOut, unsigned Frames))
|
void CVideo::NextAudioFrame(void (*Mix)(short *pFinalOut, unsigned Frames))
|
||||||
{
|
{
|
||||||
if (m_NextaFrame && m_Recording && m_HasAudio)
|
if(m_NextAudioFrame && m_Recording && m_HasAudio)
|
||||||
{
|
{
|
||||||
m_ProcessingAudioFrame = true;
|
m_ProcessingAudioFrame = true;
|
||||||
//dbg_msg("video recorder", "video_frame: %lf", (double)(m_vframe/m_FPS));
|
//dbg_msg("video recorder", "video_frame: %lf", (double)(m_Vframe/m_FPS));
|
||||||
//if((double)(m_vframe/m_FPS) < m_AudioStream.enc->frame_number*m_AudioStream.enc->frame_size/m_AudioStream.enc->sample_rate)
|
//if((double)(m_Vframe/m_FPS) < m_AudioStream.pEnc->frame_number*m_AudioStream.pEnc->frame_size/m_AudioStream.pEnc->sample_rate)
|
||||||
//return;
|
//return;
|
||||||
Mix(m_aBuffer, ALEN);
|
Mix(m_aBuffer, ALEN);
|
||||||
//m_AudioStream.frame->pts = m_AudioStream.enc->frame_number;
|
//m_AudioStream.pFrame->pts = m_AudioStream.pEnc->frame_number;
|
||||||
dbg_msg("video_recorder", "aframe: %d", m_AudioStream.enc->frame_number);
|
dbg_msg("video_recorder", "aframe: %d", m_AudioStream.pEnc->frame_number);
|
||||||
|
|
||||||
// memcpy(m_AudioStream.tmp_frame->data[0], pData, sizeof(int16_t) * m_SndBufferSize * 2);
|
// memcpy(m_AudioStream.pTmpFrame->data[0], pData, sizeof(int16_t) * m_SndBufferSize * 2);
|
||||||
//
|
//
|
||||||
// for (int i = 0; i < m_SndBufferSize; i++)
|
// for(int i = 0; i < m_SndBufferSize; i++)
|
||||||
// {
|
// {
|
||||||
// dbg_msg("video_recorder", "test: %d %d", ((int16_t*)pData)[i*2], ((int16_t*)pData)[i*2 + 1]);
|
// dbg_msg("video_recorder", "test: %d %d", ((int16_t*)pData)[i*2], ((int16_t*)pData)[i*2 + 1]);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
int dst_nb_samples;
|
int DstNbSamples;
|
||||||
|
|
||||||
av_samples_fill_arrays(
|
av_samples_fill_arrays(
|
||||||
(uint8_t**)m_AudioStream.tmp_frame->data,
|
(uint8_t**)m_AudioStream.pTmpFrame->data,
|
||||||
0, // pointer to linesize (int*)
|
0, // pointer to linesize (int*)
|
||||||
(const uint8_t*)m_aBuffer,
|
(const uint8_t*)m_aBuffer,
|
||||||
2, // channels
|
2, // channels
|
||||||
m_AudioStream.tmp_frame->nb_samples,
|
m_AudioStream.pTmpFrame->nb_samples,
|
||||||
AV_SAMPLE_FMT_S16,
|
AV_SAMPLE_FMT_S16,
|
||||||
0 // align
|
0 // align
|
||||||
);
|
);
|
||||||
|
|
||||||
dst_nb_samples = av_rescale_rnd(
|
DstNbSamples = av_rescale_rnd(
|
||||||
swr_get_delay(
|
swr_get_delay(
|
||||||
m_AudioStream.swr_ctx,
|
m_AudioStream.pSwrCtx,
|
||||||
m_AudioStream.enc->sample_rate
|
m_AudioStream.pEnc->sample_rate
|
||||||
) + m_AudioStream.tmp_frame->nb_samples,
|
) + m_AudioStream.pTmpFrame->nb_samples,
|
||||||
|
|
||||||
m_AudioStream.enc->sample_rate,
|
m_AudioStream.pEnc->sample_rate,
|
||||||
m_AudioStream.enc->sample_rate, AV_ROUND_UP
|
m_AudioStream.pEnc->sample_rate, AV_ROUND_UP
|
||||||
);
|
);
|
||||||
|
|
||||||
// dbg_msg("video_recorder", "dst_nb_samples: %d", dst_nb_samples);
|
// dbg_msg("video_recorder", "DstNbSamples: %d", DstNbSamples);
|
||||||
// fwrite(m_aBuffer, sizeof(short), 2048, m_dbgfile);
|
// fwrite(m_aBuffer, sizeof(short), 2048, m_dbgfile);
|
||||||
|
|
||||||
|
|
||||||
int ret = av_frame_make_writable(m_AudioStream.frame);
|
int Ret = av_frame_make_writable(m_AudioStream.pFrame);
|
||||||
if (ret < 0)
|
if(Ret < 0)
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
/* convert to destination format */
|
/* convert to destination format */
|
||||||
ret = swr_convert(
|
Ret = swr_convert(
|
||||||
m_AudioStream.swr_ctx,
|
m_AudioStream.pSwrCtx,
|
||||||
m_AudioStream.frame->data,
|
m_AudioStream.pFrame->data,
|
||||||
m_AudioStream.frame->nb_samples,
|
m_AudioStream.pFrame->nb_samples,
|
||||||
(const uint8_t **)m_AudioStream.tmp_frame->data,
|
(const uint8_t **)m_AudioStream.pTmpFrame->data,
|
||||||
m_AudioStream.tmp_frame->nb_samples
|
m_AudioStream.pTmpFrame->nb_samples
|
||||||
);
|
);
|
||||||
|
|
||||||
if (ret < 0)
|
if(Ret < 0)
|
||||||
{
|
{
|
||||||
dbg_msg("video_recorder", "Error while converting");
|
dbg_msg("video_recorder", "Error while converting");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -337,35 +337,32 @@ void CVideo::nextAudioFrame(void (*Mix)(short *pFinalOut, unsigned Frames))
|
||||||
|
|
||||||
// frame = ost->frame;
|
// frame = ost->frame;
|
||||||
//
|
//
|
||||||
m_AudioStream.frame->pts = av_rescale_q(m_AudioStream.samples_count, AVRational{1, m_AudioStream.enc->sample_rate}, m_AudioStream.enc->time_base);
|
m_AudioStream.pFrame->pts = av_rescale_q(m_AudioStream.SamplesCount, AVRational{1, m_AudioStream.pEnc->sample_rate}, m_AudioStream.pEnc->time_base);
|
||||||
m_AudioStream.samples_count += dst_nb_samples;
|
m_AudioStream.SamplesCount += DstNbSamples;
|
||||||
|
|
||||||
// dbg_msg("video_recorder", "prewrite----");
|
// dbg_msg("video_recorder", "prewrite----");
|
||||||
lock_wait(m_WriteLock);
|
lock_wait(g_WriteLock);
|
||||||
write_frame(&m_AudioStream);
|
WriteFrame(&m_AudioStream);
|
||||||
lock_unlock(m_WriteLock);
|
lock_unlock(g_WriteLock);
|
||||||
|
|
||||||
m_ProcessingAudioFrame = false;
|
m_ProcessingAudioFrame = false;
|
||||||
m_NextaFrame = false;
|
m_NextAudioFrame = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVideo::fill_audio_frame()
|
void CVideo::FillAudioFrame()
|
||||||
{
|
{
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVideo::fill_video_frame()
|
void CVideo::FillVideoFrame()
|
||||||
{
|
{
|
||||||
const int in_linesize[1] = { 3 * m_VideoStream.enc->width };
|
const int InLinesize[1] = { 3 * m_VideoStream.pEnc->width };
|
||||||
sws_scale(m_VideoStream.sws_ctx, (const uint8_t * const *)&m_pRGB, in_linesize, 0,
|
sws_scale(m_VideoStream.pSwsCtx, (const uint8_t * const *)&m_pRGB, InLinesize, 0,
|
||||||
m_VideoStream.enc->height, m_VideoStream.frame->data, m_VideoStream.frame->linesize);
|
m_VideoStream.pEnc->height, m_VideoStream.pFrame->data, m_VideoStream.pFrame->linesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVideo::read_rgb_from_gl()
|
void CVideo::ReadRGBFromGL()
|
||||||
{
|
{
|
||||||
int i, j, k;
|
|
||||||
size_t cur_gl, cur_rgb;
|
|
||||||
/* Get RGBA to align to 32 bits instead of just 24 for RGB. May be faster for FFmpeg. */
|
/* Get RGBA to align to 32 bits instead of just 24 for RGB. May be faster for FFmpeg. */
|
||||||
glReadBuffer(GL_FRONT);
|
glReadBuffer(GL_FRONT);
|
||||||
GLint Alignment;
|
GLint Alignment;
|
||||||
|
@ -373,92 +370,92 @@ void CVideo::read_rgb_from_gl()
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
glReadPixels(0, 0, m_Width, m_Height, GL_RGB, GL_UNSIGNED_BYTE, m_pPixels);
|
glReadPixels(0, 0, m_Width, m_Height, GL_RGB, GL_UNSIGNED_BYTE, m_pPixels);
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, Alignment);
|
glPixelStorei(GL_PACK_ALIGNMENT, Alignment);
|
||||||
for (i = 0; i < m_Height; i++)
|
for(int i = 0; i < m_Height; i++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < m_Width; j++)
|
for(int j = 0; j < m_Width; j++)
|
||||||
{
|
{
|
||||||
cur_gl = format_nchannels * (m_Width * (m_Height - i - 1) + j);
|
size_t CurGL = FORMAT_NCHANNELS * (m_Width * (m_Height - i - 1) + j);
|
||||||
cur_rgb = format_nchannels * (m_Width * i + j);
|
size_t CurRGB = FORMAT_NCHANNELS * (m_Width * i + j);
|
||||||
for (k = 0; k < (int)format_nchannels; k++)
|
for(int k = 0; k < (int)FORMAT_NCHANNELS; k++)
|
||||||
m_pRGB[cur_rgb + k] = m_pPixels[cur_gl + k];
|
m_pRGB[CurRGB + k] = m_pPixels[CurGL + k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AVFrame* CVideo::alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
|
AVFrame* CVideo::AllocPicture(enum AVPixelFormat PixFmt, int Width, int Height)
|
||||||
{
|
{
|
||||||
AVFrame* picture;
|
AVFrame* pPicture;
|
||||||
int ret;
|
int Ret;
|
||||||
|
|
||||||
picture = av_frame_alloc();
|
pPicture = av_frame_alloc();
|
||||||
if (!picture)
|
if(!pPicture)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
picture->format = pix_fmt;
|
pPicture->format = PixFmt;
|
||||||
picture->width = width;
|
pPicture->width = Width;
|
||||||
picture->height = height;
|
pPicture->height = Height;
|
||||||
|
|
||||||
/* allocate the buffers for the frame data */
|
/* allocate the buffers for the frame data */
|
||||||
ret = av_frame_get_buffer(picture, 32);
|
Ret = av_frame_get_buffer(pPicture, 32);
|
||||||
if (ret < 0) {
|
if(Ret < 0) {
|
||||||
dbg_msg("video_recorder", "Could not allocate frame data.");
|
dbg_msg("video_recorder", "Could not allocate frame data.");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return picture;
|
return pPicture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AVFrame* CVideo::alloc_audio_frame(enum AVSampleFormat sample_fmt, uint64_t channel_layout, int sample_rate, int nb_samples)
|
AVFrame* CVideo::AllocAudioFrame(enum AVSampleFormat SampleFmt, uint64_t ChannelLayout, int SampleRate, int NbSamples)
|
||||||
{
|
{
|
||||||
AVFrame *frame = av_frame_alloc();
|
AVFrame *Frame = av_frame_alloc();
|
||||||
int ret;
|
int Ret;
|
||||||
|
|
||||||
if (!frame) {
|
if(!Frame) {
|
||||||
dbg_msg("video_recorder", "Error allocating an audio frame");
|
dbg_msg("video_recorder", "Error allocating an audio frame");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->format = sample_fmt;
|
Frame->format = SampleFmt;
|
||||||
frame->channel_layout = channel_layout;
|
Frame->channel_layout = ChannelLayout;
|
||||||
frame->sample_rate = sample_rate;
|
Frame->sample_rate = SampleRate;
|
||||||
frame->nb_samples = nb_samples;
|
Frame->nb_samples = NbSamples;
|
||||||
|
|
||||||
if (nb_samples) {
|
if(NbSamples) {
|
||||||
ret = av_frame_get_buffer(frame, 0);
|
Ret = av_frame_get_buffer(Frame, 0);
|
||||||
if (ret < 0) {
|
if(Ret < 0) {
|
||||||
dbg_msg("video_recorder", "Error allocating an audio buffer");
|
dbg_msg("video_recorder", "Error allocating an audio buffer");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return frame;
|
return Frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CVideo::open_video()
|
void CVideo::OpenVideo()
|
||||||
{
|
{
|
||||||
int ret;
|
int Ret;
|
||||||
AVCodecContext* c = m_VideoStream.enc;
|
AVCodecContext* c = m_VideoStream.pEnc;
|
||||||
AVDictionary* opt = 0;
|
AVDictionary* opt = 0;
|
||||||
|
|
||||||
av_dict_copy(&opt, m_pOptDict, 0);
|
av_dict_copy(&opt, m_pOptDict, 0);
|
||||||
|
|
||||||
/* open the codec */
|
/* open the codec */
|
||||||
ret = avcodec_open2(c, m_VideoCodec, &opt);
|
Ret = avcodec_open2(c, m_VideoCodec, &opt);
|
||||||
av_dict_free(&opt);
|
av_dict_free(&opt);
|
||||||
if (ret < 0)
|
if(Ret < 0)
|
||||||
{
|
{
|
||||||
char aBuf[AV_ERROR_MAX_STRING_SIZE];
|
char aBuf[AV_ERROR_MAX_STRING_SIZE];
|
||||||
av_strerror(ret, aBuf, sizeof(aBuf));
|
av_strerror(Ret, aBuf, sizeof(aBuf));
|
||||||
dbg_msg("video_recorder", "Could not open video codec: %s", aBuf);
|
dbg_msg("video_recorder", "Could not open video codec: %s", aBuf);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate and init a re-usable frame */
|
/* allocate and init a re-usable frame */
|
||||||
m_VideoStream.frame = alloc_picture(c->pix_fmt, c->width, c->height);
|
m_VideoStream.pFrame = AllocPicture(c->pix_fmt, c->width, c->height);
|
||||||
if (!m_VideoStream.frame)
|
if(!m_VideoStream.pFrame)
|
||||||
{
|
{
|
||||||
dbg_msg("video_recorder", "Could not allocate video frame");
|
dbg_msg("video_recorder", "Could not allocate video frame");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -467,11 +464,11 @@ void CVideo::open_video()
|
||||||
/* If the output format is not YUV420P, then a temporary YUV420P
|
/* If the output format is not YUV420P, then a temporary YUV420P
|
||||||
* picture is needed too. It is then converted to the required
|
* picture is needed too. It is then converted to the required
|
||||||
* output format. */
|
* output format. */
|
||||||
m_VideoStream.tmp_frame = NULL;
|
m_VideoStream.pTmpFrame = NULL;
|
||||||
if (c->pix_fmt != AV_PIX_FMT_YUV420P)
|
if(c->pix_fmt != AV_PIX_FMT_YUV420P)
|
||||||
{
|
{
|
||||||
m_VideoStream.tmp_frame = alloc_picture(AV_PIX_FMT_YUV420P, c->width, c->height);
|
m_VideoStream.pTmpFrame = AllocPicture(AV_PIX_FMT_YUV420P, c->width, c->height);
|
||||||
if (!m_VideoStream.tmp_frame)
|
if(!m_VideoStream.pTmpFrame)
|
||||||
{
|
{
|
||||||
dbg_msg("video_recorder", "Could not allocate temporary picture");
|
dbg_msg("video_recorder", "Could not allocate temporary picture");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -479,71 +476,71 @@ void CVideo::open_video()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy the stream parameters to the muxer */
|
/* copy the stream parameters to the muxer */
|
||||||
ret = avcodec_parameters_from_context(m_VideoStream.st->codecpar, c);
|
Ret = avcodec_parameters_from_context(m_VideoStream.pSt->codecpar, c);
|
||||||
if (ret < 0)
|
if(Ret < 0)
|
||||||
{
|
{
|
||||||
dbg_msg("video_recorder", "Could not copy the stream parameters");
|
dbg_msg("video_recorder", "Could not copy the stream parameters");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
m_vseq = 0;
|
m_Vseq = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CVideo::open_audio()
|
void CVideo::OpenAudio()
|
||||||
{
|
{
|
||||||
AVCodecContext *c;
|
AVCodecContext *c;
|
||||||
int nb_samples;
|
int NbSamples;
|
||||||
int ret;
|
int Ret;
|
||||||
AVDictionary *opt = NULL;
|
AVDictionary *opt = NULL;
|
||||||
|
|
||||||
c = m_AudioStream.enc;
|
c = m_AudioStream.pEnc;
|
||||||
|
|
||||||
/* open it */
|
/* open it */
|
||||||
//m_dbgfile = fopen("/tmp/pcm_dbg", "wb");
|
//m_dbgfile = fopen("/tmp/pcm_dbg", "wb");
|
||||||
av_dict_copy(&opt, m_pOptDict, 0);
|
av_dict_copy(&opt, m_pOptDict, 0);
|
||||||
ret = avcodec_open2(c, m_AudioCodec, &opt);
|
Ret = avcodec_open2(c, m_AudioCodec, &opt);
|
||||||
av_dict_free(&opt);
|
av_dict_free(&opt);
|
||||||
if (ret < 0)
|
if(Ret < 0)
|
||||||
{
|
{
|
||||||
char aBuf[AV_ERROR_MAX_STRING_SIZE];
|
char aBuf[AV_ERROR_MAX_STRING_SIZE];
|
||||||
av_strerror(ret, aBuf, sizeof(aBuf));
|
av_strerror(Ret, aBuf, sizeof(aBuf));
|
||||||
dbg_msg("video_recorder", "Could not open audio codec: %s", aBuf);
|
dbg_msg("video_recorder", "Could not open audio codec: %s", aBuf);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
|
if(c->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
|
||||||
nb_samples = 10000;
|
NbSamples = 10000;
|
||||||
else
|
else
|
||||||
nb_samples = c->frame_size;
|
NbSamples = c->frame_size;
|
||||||
|
|
||||||
m_AudioStream.frame = alloc_audio_frame(c->sample_fmt, c->channel_layout, c->sample_rate, nb_samples);
|
m_AudioStream.pFrame = AllocAudioFrame(c->sample_fmt, c->channel_layout, c->sample_rate, NbSamples);
|
||||||
|
|
||||||
m_AudioStream.tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, AV_CH_LAYOUT_STEREO, g_Config.m_SndRate, m_SndBufferSize * 2);
|
m_AudioStream.pTmpFrame = AllocAudioFrame(AV_SAMPLE_FMT_S16, AV_CH_LAYOUT_STEREO, g_Config.m_SndRate, m_SndBufferSize * 2);
|
||||||
|
|
||||||
/* copy the stream parameters to the muxer */
|
/* copy the stream parameters to the muxer */
|
||||||
ret = avcodec_parameters_from_context(m_AudioStream.st->codecpar, c);
|
Ret = avcodec_parameters_from_context(m_AudioStream.pSt->codecpar, c);
|
||||||
if (ret < 0) {
|
if(Ret < 0) {
|
||||||
dbg_msg("video_recorder", "Could not copy the stream parameters");
|
dbg_msg("video_recorder", "Could not copy the stream parameters");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create resampler context */
|
/* create resampler context */
|
||||||
m_AudioStream.swr_ctx = swr_alloc();
|
m_AudioStream.pSwrCtx = swr_alloc();
|
||||||
if (!m_AudioStream.swr_ctx) {
|
if(!m_AudioStream.pSwrCtx) {
|
||||||
dbg_msg("video_recorder", "Could not allocate resampler context");
|
dbg_msg("video_recorder", "Could not allocate resampler context");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set options */
|
/* set options */
|
||||||
av_opt_set_int (m_AudioStream.swr_ctx, "in_channel_count", 2, 0);
|
av_opt_set_int(m_AudioStream.pSwrCtx, "in_channel_count", 2, 0);
|
||||||
av_opt_set_int (m_AudioStream.swr_ctx, "in_sample_rate", g_Config.m_SndRate, 0);
|
av_opt_set_int(m_AudioStream.pSwrCtx, "in_sample_rate", g_Config.m_SndRate, 0);
|
||||||
av_opt_set_sample_fmt(m_AudioStream.swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
|
av_opt_set_sample_fmt(m_AudioStream.pSwrCtx, "in_SampleFmt", AV_SAMPLE_FMT_S16, 0);
|
||||||
av_opt_set_int (m_AudioStream.swr_ctx, "out_channel_count", c->channels, 0);
|
av_opt_set_int(m_AudioStream.pSwrCtx, "out_channel_count", c->channels, 0);
|
||||||
av_opt_set_int (m_AudioStream.swr_ctx, "out_sample_rate", c->sample_rate, 0);
|
av_opt_set_int(m_AudioStream.pSwrCtx, "out_sample_rate", c->sample_rate, 0);
|
||||||
av_opt_set_sample_fmt(m_AudioStream.swr_ctx, "out_sample_fmt", c->sample_fmt, 0);
|
av_opt_set_sample_fmt(m_AudioStream.pSwrCtx, "out_SampleFmt", c->sample_fmt, 0);
|
||||||
|
|
||||||
/* initialize the resampling context */
|
/* initialize the resampling context */
|
||||||
if ((ret = swr_init(m_AudioStream.swr_ctx)) < 0) {
|
if((Ret = swr_init(m_AudioStream.pSwrCtx)) < 0) {
|
||||||
dbg_msg("video_recorder", "Failed to initialize the resampling context");
|
dbg_msg("video_recorder", "Failed to initialize the resampling context");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -553,35 +550,35 @@ void CVideo::open_audio()
|
||||||
|
|
||||||
|
|
||||||
/* Add an output stream. */
|
/* Add an output stream. */
|
||||||
void CVideo::add_stream(OutputStream *ost, AVFormatContext *oc, AVCodec **codec, enum AVCodecID codec_id)
|
void CVideo::AddStream(OutputStream *pStream, AVFormatContext *pOC, AVCodec **ppCodec, enum AVCodecID CodecId)
|
||||||
{
|
{
|
||||||
AVCodecContext *c;
|
AVCodecContext *c;
|
||||||
|
|
||||||
/* find the encoder */
|
/* find the encoder */
|
||||||
*codec = avcodec_find_encoder(codec_id);
|
*ppCodec= avcodec_find_encoder(CodecId);
|
||||||
if (!(*codec))
|
if(!(*ppCodec))
|
||||||
{
|
{
|
||||||
dbg_msg("video_recorder", "Could not find encoder for '%s'",
|
dbg_msg("video_recorder", "Could not find encoder for '%s'",
|
||||||
avcodec_get_name(codec_id));
|
avcodec_get_name(CodecId));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ost->st = avformat_new_stream(oc, NULL);
|
pStream->pSt = avformat_new_stream(pOC, NULL);
|
||||||
if (!ost->st)
|
if(!pStream->pSt)
|
||||||
{
|
{
|
||||||
dbg_msg("video_recorder", "Could not allocate stream");
|
dbg_msg("video_recorder", "Could not allocate stream");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
ost->st->id = oc->nb_streams-1;
|
pStream->pSt->id = pOC->nb_streams-1;
|
||||||
c = avcodec_alloc_context3(*codec);
|
c = avcodec_alloc_context3(*ppCodec);
|
||||||
if (!c)
|
if(!c)
|
||||||
{
|
{
|
||||||
dbg_msg("video_recorder", "Could not alloc an encoding context");
|
dbg_msg("video_recorder", "Could not alloc an encoding context");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
ost->enc = c;
|
pStream->pEnc = c;
|
||||||
|
|
||||||
switch ((*codec)->type)
|
switch ((*ppCodec)->type)
|
||||||
{
|
{
|
||||||
case AVMEDIA_TYPE_AUDIO:
|
case AVMEDIA_TYPE_AUDIO:
|
||||||
|
|
||||||
|
@ -593,28 +590,28 @@ void CVideo::add_stream(OutputStream *ost, AVFormatContext *oc, AVCodec **codec,
|
||||||
// Format.channels = 2; // ignore_convention
|
// Format.channels = 2; // ignore_convention
|
||||||
// Format.samples = g_Config.m_SndBufferSize; // ignore_convention
|
// Format.samples = g_Config.m_SndBufferSize; // ignore_convention
|
||||||
|
|
||||||
c->sample_fmt = (*codec)->sample_fmts ? (*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
|
c->sample_fmt = (*ppCodec)->sample_fmts ? (*ppCodec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
|
||||||
c->bit_rate = g_Config.m_SndRate * 2 * 16;
|
c->bit_rate = g_Config.m_SndRate * 2 * 16;
|
||||||
c->frame_size = m_SndBufferSize;
|
c->frame_size = m_SndBufferSize;
|
||||||
c->sample_rate = g_Config.m_SndRate;
|
c->sample_rate = g_Config.m_SndRate;
|
||||||
if ((*codec)->supported_samplerates)
|
if((*ppCodec)->supported_samplerates)
|
||||||
{
|
{
|
||||||
c->sample_rate = (*codec)->supported_samplerates[0];
|
c->sample_rate = (*ppCodec)->supported_samplerates[0];
|
||||||
for (int i = 0; (*codec)->supported_samplerates[i]; i++)
|
for(int i = 0; (*ppCodec)->supported_samplerates[i]; i++)
|
||||||
{
|
{
|
||||||
if ((*codec)->supported_samplerates[i] == g_Config.m_SndRate)
|
if((*ppCodec)->supported_samplerates[i] == g_Config.m_SndRate)
|
||||||
c->sample_rate = g_Config.m_SndRate;
|
c->sample_rate = g_Config.m_SndRate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c->channels = 2;
|
c->channels = 2;
|
||||||
c->channel_layout = AV_CH_LAYOUT_STEREO;
|
c->channel_layout = AV_CH_LAYOUT_STEREO;
|
||||||
|
|
||||||
ost->st->time_base.num = 1;
|
pStream->pSt->time_base.num = 1;
|
||||||
ost->st->time_base.den = c->sample_rate;
|
pStream->pSt->time_base.den = c->sample_rate;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AVMEDIA_TYPE_VIDEO:
|
case AVMEDIA_TYPE_VIDEO:
|
||||||
c->codec_id = codec_id;
|
c->codec_id = CodecId;
|
||||||
|
|
||||||
c->bit_rate = 400000;
|
c->bit_rate = 400000;
|
||||||
/* Resolution must be a multiple of two. */
|
/* Resolution must be a multiple of two. */
|
||||||
|
@ -624,25 +621,25 @@ void CVideo::add_stream(OutputStream *ost, AVFormatContext *oc, AVCodec **codec,
|
||||||
* of which frame timestamps are represented. For fixed-fps content,
|
* of which frame timestamps are represented. For fixed-fps content,
|
||||||
* timebase should be 1/framerate and timestamp increments should be
|
* timebase should be 1/framerate and timestamp increments should be
|
||||||
* identical to 1. */
|
* identical to 1. */
|
||||||
ost->st->time_base.num = 1;
|
pStream->pSt->time_base.num = 1;
|
||||||
ost->st->time_base.den = m_FPS;
|
pStream->pSt->time_base.den = m_FPS;
|
||||||
c->time_base = ost->st->time_base;
|
c->time_base = pStream->pSt->time_base;
|
||||||
|
|
||||||
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
|
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
|
||||||
c->pix_fmt = STREAM_PIX_FMT;
|
c->pix_fmt = STREAM_PIX_FMT;
|
||||||
if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
|
if(c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
|
||||||
{
|
{
|
||||||
/* just for testing, we also add B-frames */
|
/* just for testing, we also add B-frames */
|
||||||
c->max_b_frames = 2;
|
c->max_b_frames = 2;
|
||||||
}
|
}
|
||||||
if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
|
if(c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
|
||||||
{
|
{
|
||||||
/* Needed to avoid using macroblocks in which some coeffs overflow.
|
/* Needed to avoid using macroblocks in which some coeffs overflow.
|
||||||
* This does not happen with normal video, it just happens here as
|
* This does not happen with normal video, it just happens here as
|
||||||
* the motion of the chroma plane does not match the luma plane. */
|
* the motion of the chroma plane does not match the luma plane. */
|
||||||
c->mb_decision = 2;
|
c->mb_decision = 2;
|
||||||
}
|
}
|
||||||
if (codec_id == AV_CODEC_ID_H264)
|
if(CodecId == AV_CODEC_ID_H264)
|
||||||
{
|
{
|
||||||
const char *presets[10] = {"ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo"};
|
const char *presets[10] = {"ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo"};
|
||||||
//av_opt_set(c->priv_data, "preset", "slow", 0);
|
//av_opt_set(c->priv_data, "preset", "slow", 0);
|
||||||
|
@ -657,16 +654,16 @@ void CVideo::add_stream(OutputStream *ost, AVFormatContext *oc, AVCodec **codec,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Some formats want stream headers to be separate. */
|
/* Some formats want stream headers to be separate. */
|
||||||
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
|
if(pOC->oformat->flags & AVFMT_GLOBALHEADER)
|
||||||
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void CVideo::write_frame(OutputStream* pStream)
|
void CVideo::WriteFrame(OutputStream* pStream)
|
||||||
{
|
{
|
||||||
//lock_wait(m_WriteLock);
|
//lock_wait(g_WriteLock);
|
||||||
int ret_recv = 0;
|
int RetRecv = 0;
|
||||||
|
|
||||||
AVPacket Packet = { 0 };
|
AVPacket Packet = { 0 };
|
||||||
|
|
||||||
|
@ -674,38 +671,38 @@ void CVideo::write_frame(OutputStream* pStream)
|
||||||
Packet.data = 0;
|
Packet.data = 0;
|
||||||
Packet.size = 0;
|
Packet.size = 0;
|
||||||
|
|
||||||
avcodec_send_frame(pStream->enc, pStream->frame);
|
avcodec_send_frame(pStream->pEnc, pStream->pFrame);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ret_recv = avcodec_receive_packet(pStream->enc, &Packet);
|
RetRecv = avcodec_receive_packet(pStream->pEnc, &Packet);
|
||||||
if (!ret_recv)
|
if(!RetRecv)
|
||||||
{
|
{
|
||||||
/* rescale output packet timestamp values from codec to stream timebase */
|
/* rescale output packet timestamp values from codec to stream timebase */
|
||||||
av_packet_rescale_ts(&Packet, pStream->enc->time_base, pStream->st->time_base);
|
av_packet_rescale_ts(&Packet, pStream->pEnc->time_base, pStream->pSt->time_base);
|
||||||
Packet.stream_index = pStream->st->index;
|
Packet.stream_index = pStream->pSt->index;
|
||||||
|
|
||||||
if (int ret = av_interleaved_write_frame(m_pFormatContext, &Packet))
|
if(int Ret = av_interleaved_write_frame(m_pFormatContext, &Packet))
|
||||||
{
|
{
|
||||||
char aBuf[AV_ERROR_MAX_STRING_SIZE];
|
char aBuf[AV_ERROR_MAX_STRING_SIZE];
|
||||||
av_strerror(ret, aBuf, sizeof(aBuf));
|
av_strerror(Ret, aBuf, sizeof(aBuf));
|
||||||
dbg_msg("video_recorder", "Error while writing video frame: %s", aBuf);
|
dbg_msg("video_recorder", "Error while writing video frame: %s", aBuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
} while (true);
|
} while(true);
|
||||||
|
|
||||||
if (ret_recv && ret_recv != AVERROR(EAGAIN))
|
if(RetRecv && RetRecv != AVERROR(EAGAIN))
|
||||||
{
|
{
|
||||||
dbg_msg("video_recorder", "Error encoding frame, error: %d", ret_recv);
|
dbg_msg("video_recorder", "Error encoding frame, error: %d", RetRecv);
|
||||||
}
|
}
|
||||||
//lock_unlock(m_WriteLock);
|
//lock_unlock(g_WriteLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVideo::finish_frames(OutputStream* pStream)
|
void CVideo::FinishFrames(OutputStream* pStream)
|
||||||
{
|
{
|
||||||
dbg_msg("video_recorder", "------------");
|
dbg_msg("video_recorder", "------------");
|
||||||
int ret_recv = 0;
|
int RetRecv = 0;
|
||||||
|
|
||||||
AVPacket Packet = { 0 };
|
AVPacket Packet = { 0 };
|
||||||
|
|
||||||
|
@ -713,41 +710,41 @@ void CVideo::finish_frames(OutputStream* pStream)
|
||||||
Packet.data = 0;
|
Packet.data = 0;
|
||||||
Packet.size = 0;
|
Packet.size = 0;
|
||||||
|
|
||||||
avcodec_send_frame(pStream->enc, 0);
|
avcodec_send_frame(pStream->pEnc, 0);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ret_recv = avcodec_receive_packet(pStream->enc, &Packet);
|
RetRecv = avcodec_receive_packet(pStream->pEnc, &Packet);
|
||||||
if (!ret_recv)
|
if(!RetRecv)
|
||||||
{
|
{
|
||||||
/* rescale output packet timestamp values from codec to stream timebase */
|
/* rescale output packet timestamp values from codec to stream timebase */
|
||||||
//if(pStream->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
|
//if(pStream->pSt->codec->codec_type == AVMEDIA_TYPE_AUDIO)
|
||||||
av_packet_rescale_ts(&Packet, pStream->enc->time_base, pStream->st->time_base);
|
av_packet_rescale_ts(&Packet, pStream->pEnc->time_base, pStream->pSt->time_base);
|
||||||
Packet.stream_index = pStream->st->index;
|
Packet.stream_index = pStream->pSt->index;
|
||||||
|
|
||||||
if (int ret = av_interleaved_write_frame(m_pFormatContext, &Packet))
|
if(int Ret = av_interleaved_write_frame(m_pFormatContext, &Packet))
|
||||||
{
|
{
|
||||||
char aBuf[AV_ERROR_MAX_STRING_SIZE];
|
char aBuf[AV_ERROR_MAX_STRING_SIZE];
|
||||||
av_strerror(ret, aBuf, sizeof(aBuf));
|
av_strerror(Ret, aBuf, sizeof(aBuf));
|
||||||
dbg_msg("video_recorder", "Error while writing video frame: %s", aBuf);
|
dbg_msg("video_recorder", "Error while writing video frame: %s", aBuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
} while (true);
|
} while(true);
|
||||||
|
|
||||||
if (ret_recv && ret_recv != AVERROR_EOF)
|
if(RetRecv && RetRecv != AVERROR_EOF)
|
||||||
{
|
{
|
||||||
dbg_msg("video_recorder", "failed to finish recoding, error: %d", ret_recv);
|
dbg_msg("video_recorder", "failed to finish recoding, error: %d", RetRecv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVideo::close_stream(OutputStream* ost)
|
void CVideo::CloseStream(OutputStream* pStream)
|
||||||
{
|
{
|
||||||
avcodec_free_context(&ost->enc);
|
avcodec_free_context(&pStream->pEnc);
|
||||||
av_frame_free(&ost->frame);
|
av_frame_free(&pStream->pFrame);
|
||||||
av_frame_free(&ost->tmp_frame);
|
av_frame_free(&pStream->pTmpFrame);
|
||||||
sws_freeContext(ost->sws_ctx);
|
sws_freeContext(pStream->pSwsCtx);
|
||||||
swr_free(&ost->swr_ctx);
|
swr_free(&pStream->pSwrCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,18 +37,18 @@ extern "C"
|
||||||
|
|
||||||
// a wrapper around a single output AVStream
|
// a wrapper around a single output AVStream
|
||||||
typedef struct OutputStream {
|
typedef struct OutputStream {
|
||||||
AVStream *st;
|
AVStream *pSt;
|
||||||
AVCodecContext *enc;
|
AVCodecContext *pEnc;
|
||||||
|
|
||||||
/* pts of the next frame that will be generated */
|
/* pts of the next frame that will be generated */
|
||||||
int64_t next_pts;
|
int64_t NextPts;
|
||||||
int samples_count;
|
int SamplesCount;
|
||||||
|
|
||||||
AVFrame *frame;
|
AVFrame *pFrame;
|
||||||
AVFrame *tmp_frame;
|
AVFrame *pTmpFrame;
|
||||||
|
|
||||||
struct SwsContext *sws_ctx;
|
struct SwsContext *pSwsCtx;
|
||||||
struct SwrContext *swr_ctx;
|
struct SwrContext *pSwrCtx;
|
||||||
} OutputStream;
|
} OutputStream;
|
||||||
|
|
||||||
class CVideo : public IVideo
|
class CVideo : public IVideo
|
||||||
|
@ -57,38 +57,39 @@ public:
|
||||||
CVideo(class CGraphics_Threaded* pGraphics, class IStorage* pStorage, class IConsole *pConsole, int width, int height, const char *name);
|
CVideo(class CGraphics_Threaded* pGraphics, class IStorage* pStorage, class IConsole *pConsole, int width, int height, const char *name);
|
||||||
~CVideo();
|
~CVideo();
|
||||||
|
|
||||||
virtual void start();
|
virtual void Start();
|
||||||
virtual void stop();
|
virtual void Stop();
|
||||||
virtual void pause(bool p);
|
virtual void Pause(bool Pause);
|
||||||
|
virtual bool IsRecording() { return m_Recording; }
|
||||||
|
|
||||||
virtual void nextVideoFrame();
|
virtual void NextVideoFrame();
|
||||||
virtual void nextVideoFrame_thread();
|
virtual void NextVideoFrameThread();
|
||||||
virtual bool frameRendered() { return !m_NextFrame; }
|
virtual bool FrameRendered() { return !m_NextFrame; }
|
||||||
|
|
||||||
virtual void nextAudioFrame(void (*Mix)(short *pFinalOut, unsigned Frames));
|
virtual void NextAudioFrame(void (*Mix)(short *pFinalOut, unsigned Frames));
|
||||||
virtual void nextAudioFrame_timeline();
|
virtual void NextAudioFrameTimeline();
|
||||||
virtual bool aframeRendered() { return !m_NextaFrame; }
|
virtual bool AudioFrameRendered() { return !m_NextAudioFrame; }
|
||||||
|
|
||||||
static IVideo* Current() { return IVideo::ms_pCurrentVideo; }
|
static IVideo* Current() { return IVideo::ms_pCurrentVideo; }
|
||||||
|
|
||||||
static void Init() { av_log_set_level(AV_LOG_DEBUG); }
|
static void Init() { av_log_set_level(AV_LOG_DEBUG); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void fill_video_frame();
|
void FillVideoFrame();
|
||||||
void read_rgb_from_gl();
|
void ReadRGBFromGL();
|
||||||
|
|
||||||
void fill_audio_frame();
|
void FillAudioFrame();
|
||||||
|
|
||||||
void open_video();
|
void OpenVideo();
|
||||||
void open_audio();
|
void OpenAudio();
|
||||||
AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height);
|
AVFrame *AllocPicture(enum AVPixelFormat PixFmt, int Width, int Height);
|
||||||
AVFrame* alloc_audio_frame(enum AVSampleFormat sample_fmt, uint64_t channel_layout, int sample_rate, int nb_samples);
|
AVFrame* AllocAudioFrame(enum AVSampleFormat SampleFmt, uint64_t ChannelLayout, int SampleRate, int NbSamples);
|
||||||
|
|
||||||
void write_frame(OutputStream* pStream);
|
void WriteFrame(OutputStream* pStream);
|
||||||
void finish_frames(OutputStream* pStream);
|
void FinishFrames(OutputStream* pStream);
|
||||||
void close_stream(OutputStream *ost);
|
void CloseStream(OutputStream *pStream);
|
||||||
|
|
||||||
void add_stream(OutputStream *ost, AVFormatContext *oc, AVCodec **codec, enum AVCodecID codec_id);
|
void AddStream(OutputStream *pStream, AVFormatContext *pOC, AVCodec **ppCodec, enum AVCodecID CodecId);
|
||||||
|
|
||||||
class CGraphics_Threaded* m_pGraphics;
|
class CGraphics_Threaded* m_pGraphics;
|
||||||
class IStorage* m_pStorage;
|
class IStorage* m_pStorage;
|
||||||
|
@ -98,9 +99,9 @@ private:
|
||||||
int m_Height;
|
int m_Height;
|
||||||
char m_Name[256];
|
char m_Name[256];
|
||||||
//FILE *m_dbgfile;
|
//FILE *m_dbgfile;
|
||||||
int m_vseq;
|
int m_Vseq;
|
||||||
short m_aBuffer[ALEN*2];
|
short m_aBuffer[ALEN*2];
|
||||||
int m_vframe;
|
int m_Vframe;
|
||||||
|
|
||||||
int m_FPS;
|
int m_FPS;
|
||||||
|
|
||||||
|
@ -111,7 +112,7 @@ private:
|
||||||
bool m_ProcessingAudioFrame;
|
bool m_ProcessingAudioFrame;
|
||||||
|
|
||||||
bool m_NextFrame;
|
bool m_NextFrame;
|
||||||
bool m_NextaFrame;
|
bool m_NextAudioFrame;
|
||||||
|
|
||||||
bool m_HasAudio;
|
bool m_HasAudio;
|
||||||
|
|
||||||
|
|
|
@ -681,7 +681,7 @@ void CDemoPlayer::Pause()
|
||||||
m_Info.m_Info.m_Paused = 1;
|
m_Info.m_Info.m_Paused = 1;
|
||||||
#if defined(CONF_VIDEORECORDER)
|
#if defined(CONF_VIDEORECORDER)
|
||||||
if(IVideo::Current() && g_Config.m_ClVideoPauseWithDemo)
|
if(IVideo::Current() && g_Config.m_ClVideoPauseWithDemo)
|
||||||
IVideo::Current()->pause(true);
|
IVideo::Current()->Pause(true);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,7 +695,7 @@ void CDemoPlayer::Unpause()
|
||||||
}
|
}
|
||||||
#if defined(CONF_VIDEORECORDER)
|
#if defined(CONF_VIDEORECORDER)
|
||||||
if(IVideo::Current() && g_Config.m_ClVideoPauseWithDemo)
|
if(IVideo::Current() && g_Config.m_ClVideoPauseWithDemo)
|
||||||
IVideo::Current()->pause(false);
|
IVideo::Current()->Pause(false);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -884,9 +884,9 @@ int64 CDemoPlayer::time()
|
||||||
if (!s_Recording)
|
if (!s_Recording)
|
||||||
{
|
{
|
||||||
s_Recording = true;
|
s_Recording = true;
|
||||||
m_Info.m_LastUpdate = IVideo::time();
|
m_Info.m_LastUpdate = IVideo::Time();
|
||||||
}
|
}
|
||||||
return IVideo::time();
|
return IVideo::Time();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1038,7 +1038,7 @@ int CDemoPlayer::Stop()
|
||||||
{
|
{
|
||||||
#if defined(CONF_VIDEORECORDER)
|
#if defined(CONF_VIDEORECORDER)
|
||||||
if (IVideo::Current())
|
if (IVideo::Current())
|
||||||
IVideo::Current()->stop();
|
IVideo::Current()->Stop();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(!m_File)
|
if(!m_File)
|
||||||
|
|
|
@ -8,25 +8,26 @@ class IVideo
|
||||||
public:
|
public:
|
||||||
virtual ~IVideo() {};
|
virtual ~IVideo() {};
|
||||||
|
|
||||||
virtual void start() = 0;
|
virtual void Start() = 0;
|
||||||
virtual void stop() = 0;
|
virtual void Stop() = 0;
|
||||||
virtual void pause(bool p) = 0;
|
virtual void Pause(bool Pause) = 0;
|
||||||
|
virtual bool IsRecording() = 0;
|
||||||
|
|
||||||
virtual void nextVideoFrame() = 0;
|
virtual void NextVideoFrame() = 0;
|
||||||
virtual bool frameRendered() = 0;
|
virtual bool FrameRendered() = 0;
|
||||||
virtual void nextVideoFrame_thread() = 0;
|
virtual void NextVideoFrameThread() = 0;
|
||||||
|
|
||||||
virtual void nextAudioFrame(void (*Mix)(short *pFinalOut, unsigned Frames)) = 0;
|
virtual void NextAudioFrame(void (*Mix)(short *pFinalOut, unsigned Frames)) = 0;
|
||||||
virtual bool aframeRendered() = 0;
|
virtual bool AudioFrameRendered() = 0;
|
||||||
virtual void nextAudioFrame_timeline() = 0;
|
virtual void NextAudioFrameTimeline() = 0;
|
||||||
|
|
||||||
|
|
||||||
static IVideo* Current() { return ms_pCurrentVideo; }
|
static IVideo* Current() { return ms_pCurrentVideo; }
|
||||||
|
|
||||||
static int64 time() { return ms_Time; }
|
static int64 Time() { return ms_Time; }
|
||||||
static float LocalTime() { return ms_LocalTime; }
|
static float LocalTime() { return ms_LocalTime; }
|
||||||
static void SetLocalStartTime(int64 LocalStartTime) { ms_LocalStartTime = LocalStartTime; }
|
static void SetLocalStartTime(int64 LocalStartTime) { ms_LocalStartTime = LocalStartTime; }
|
||||||
static void SetFPS(int fps) { ms_TickTime = time_freq() / fps; }
|
static void SetFPS(int FPS) { ms_TickTime = time_freq() / FPS; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static IVideo* ms_pCurrentVideo;
|
static IVideo* ms_pCurrentVideo;
|
||||||
|
|
|
@ -35,7 +35,7 @@ protected:
|
||||||
class IUpdater *Updater() const { return m_pClient->Updater(); }
|
class IUpdater *Updater() const { return m_pClient->Updater(); }
|
||||||
|
|
||||||
#if defined(CONF_VIDEORECORDER)
|
#if defined(CONF_VIDEORECORDER)
|
||||||
int64 time() const { return IVideo::Current() ? IVideo::time() : time_get(); }
|
int64 time() const { return IVideo::Current() ? IVideo::Time() : time_get(); }
|
||||||
float LocalTime() const { return IVideo::Current() ? IVideo::LocalTime() : Client()->LocalTime(); }
|
float LocalTime() const { return IVideo::Current() ? IVideo::LocalTime() : Client()->LocalTime(); }
|
||||||
#else
|
#else
|
||||||
int64 time() const { return time_get(); }
|
int64 time() const { return time_get(); }
|
||||||
|
|
Loading…
Reference in a new issue