2020-03-06 13:00:06 +08:00
/*
2023-12-09 16:23:51 +08:00
* Copyright ( c ) 2016 - present The ZLMediaKit project authors . All Rights Reserved .
2020-03-06 13:00:06 +08:00
*
2023-12-09 16:23:51 +08:00
* This file is part of ZLMediaKit ( https : //github.com/ZLMediaKit/ZLMediaKit).
2020-03-06 13:00:06 +08:00
*
2023-12-09 16:23:51 +08:00
* Use of this source code is governed by MIT - like license that can be found in the
2020-04-04 20:30:09 +08:00
* LICENSE file in the root of the source tree . All contributing project authors
* may be found in the AUTHORS file in the root of the source tree .
2020-03-06 13:00:06 +08:00
*/
# include "Decoder.h"
# include "PSDecoder.h"
# include "TSDecoder.h"
2023-12-09 16:23:51 +08:00
# include "Extension/Factory.h"
2020-05-17 18:00:23 +08:00
2020-06-12 18:17:49 +08:00
# if defined(ENABLE_RTPPROXY) || defined(ENABLE_HLS)
2022-11-09 17:44:38 +08:00
# include "mpeg-ts.h"
2020-06-12 18:17:49 +08:00
# endif
2022-02-02 20:34:50 +08:00
using namespace toolkit ;
2020-03-06 13:00:06 +08:00
namespace mediakit {
2022-06-29 11:01:16 +08:00
void Decoder : : setOnDecode ( Decoder : : onDecode cb ) {
_on_decode = std : : move ( cb ) ;
}
void Decoder : : setOnStream ( Decoder : : onStream cb ) {
_on_stream = std : : move ( cb ) ;
}
2020-05-17 18:00:23 +08:00
static Decoder : : Ptr createDecoder_l ( DecoderImp : : Type type ) {
2020-03-06 13:00:06 +08:00
switch ( type ) {
2020-05-17 18:00:23 +08:00
case DecoderImp : : decoder_ps :
# ifdef ENABLE_RTPPROXY
return std : : make_shared < PSDecoder > ( ) ;
# else
WarnL < < " 创建ps解复用器失败, 请打开ENABLE_RTPPROXY然后重新编译 " ;
return nullptr ;
# endif //ENABLE_RTPPROXY
case DecoderImp : : decoder_ts :
# ifdef ENABLE_HLS
return std : : make_shared < TSDecoder > ( ) ;
# else
WarnL < < " 创建mpegts解复用器失败, 请打开ENABLE_HLS然后重新编译 " ;
return nullptr ;
# endif //ENABLE_HLS
default : return nullptr ;
}
}
/////////////////////////////////////////////////////////////
2020-05-21 11:44:57 +08:00
DecoderImp : : Ptr DecoderImp : : createDecoder ( Type type , MediaSinkInterface * sink ) {
2020-05-17 18:00:23 +08:00
auto decoder = createDecoder_l ( type ) ;
if ( ! decoder ) {
return nullptr ;
}
return DecoderImp : : Ptr ( new DecoderImp ( decoder , sink ) ) ;
}
2022-10-16 19:49:56 +08:00
void DecoderImp : : flush ( ) {
2023-12-09 22:34:22 +08:00
for ( auto & pr : _tracks ) {
pr . second . second . flush ( ) ;
}
2022-10-16 19:49:56 +08:00
}
2021-02-09 14:01:10 +08:00
ssize_t DecoderImp : : input ( const uint8_t * data , size_t bytes ) {
2020-05-17 18:00:23 +08:00
return _decoder - > input ( data , bytes ) ;
}
2020-05-21 11:44:57 +08:00
DecoderImp : : DecoderImp ( const Decoder : : Ptr & decoder , MediaSinkInterface * sink ) {
2020-05-17 18:00:23 +08:00
_decoder = decoder ;
_sink = sink ;
2021-01-17 18:31:50 +08:00
_decoder - > setOnDecode ( [ this ] ( int stream , int codecid , int flags , int64_t pts , int64_t dts , const void * data , size_t bytes ) {
2020-11-29 09:38:04 +08:00
onDecode ( stream , codecid , flags , pts , dts , data , bytes ) ;
} ) ;
2021-01-17 18:31:50 +08:00
_decoder - > setOnStream ( [ this ] ( int stream , int codecid , const void * extra , size_t bytes , int finish ) {
2020-11-29 09:38:04 +08:00
onStream ( stream , codecid , extra , bytes , finish ) ;
2020-05-17 18:00:23 +08:00
} ) ;
}
2020-06-12 18:17:49 +08:00
# if defined(ENABLE_RTPPROXY) || defined(ENABLE_HLS)
2020-05-17 18:00:23 +08:00
2023-12-09 16:23:51 +08:00
void DecoderImp : : onStream ( int stream , int codecid , const void * extra , size_t bytes , int finish ) {
2024-07-14 09:27:14 +08:00
if ( _finished ) {
return ;
}
2024-09-19 14:53:50 +08:00
// G711传统只支持 8000/1/16的规格, FFmpeg貌似做了扩展, 但是这里不管它了 [AUTO-TRANSLATED:851813f7]
// G711 traditionally only supports the 8000/1/16 specification. FFmpeg seems to have extended it, but we'll ignore that here.
2024-11-29 23:38:27 +08:00
auto codec = getCodecByMpegId ( codecid ) ;
2024-12-01 10:26:50 +08:00
if ( codec ! = CodecInvalid ) {
auto track = Factory : : getTrackByCodecId ( codec ) ;
if ( track ) {
onTrack ( stream , std : : move ( track ) ) ;
}
2020-11-29 09:38:04 +08:00
}
2024-09-19 14:53:50 +08:00
// 防止未获取视频track提前complete导致忽略后续视频的问题, 用于兼容一些不太规范的ps流 [AUTO-TRANSLATED:d6b349b5]
// Prevent the problem of ignoring subsequent video due to premature completion of the video track before it is obtained. This is used to be compatible with some non-standard PS streams.
2023-12-09 22:34:22 +08:00
if ( finish & & _have_video ) {
2024-07-14 09:27:14 +08:00
_finished = true ;
2020-11-29 09:38:04 +08:00
_sink - > addTrackCompleted ( ) ;
2023-12-09 16:23:51 +08:00
InfoL < < " Add track finished " ;
2020-11-29 09:38:04 +08:00
}
}
2023-12-09 16:23:51 +08:00
void DecoderImp : : onDecode ( int stream , int codecid , int flags , int64_t pts , int64_t dts , const void * data , size_t bytes ) {
2020-05-17 18:00:23 +08:00
pts / = 90 ;
dts / = 90 ;
2023-12-09 16:23:51 +08:00
auto codec = getCodecByMpegId ( codecid ) ;
if ( codec = = CodecInvalid ) {
return ;
}
2023-12-09 22:34:22 +08:00
auto & ref = _tracks [ stream ] ;
if ( ! ref . first ) {
2024-11-29 23:38:27 +08:00
onTrack ( stream , Factory : : getTrackByCodecId ( codec ) ) ;
2023-12-09 16:23:51 +08:00
}
2023-12-13 17:41:57 +08:00
if ( ! ref . first ) {
2023-12-14 17:28:21 +08:00
WarnL < < " Unsupported codec : " < < getCodecName ( codec ) ;
2023-12-13 17:41:57 +08:00
return ;
}
2023-12-09 22:34:22 +08:00
auto frame = Factory : : getFrameFromPtr ( codec , ( char * ) data , bytes , dts , pts ) ;
if ( getTrackType ( codec ) ! = TrackVideo ) {
onFrame ( stream , frame ) ;
return ;
2020-03-06 13:00:06 +08:00
}
2023-12-14 17:28:21 +08:00
ref . second . inputFrame ( frame , [ this , stream , codec ] ( uint64_t dts , uint64_t pts , const Buffer : : Ptr & buffer , bool ) {
2023-12-09 22:34:22 +08:00
onFrame ( stream , Factory : : getFrameFromBuffer ( codec , buffer , dts , pts ) ) ;
} ) ;
2020-03-06 13:00:06 +08:00
}
2020-06-12 18:17:49 +08:00
# else
2021-01-17 18:31:50 +08:00
void DecoderImp : : onDecode ( int stream , int codecid , int flags , int64_t pts , int64_t dts , const void * data , size_t bytes ) { }
void DecoderImp : : onStream ( int stream , int codecid , const void * extra , size_t bytes , int finish ) { }
2020-06-12 18:17:49 +08:00
# endif
2020-03-06 13:00:06 +08:00
2023-12-09 22:34:22 +08:00
void DecoderImp : : onTrack ( int index , const Track : : Ptr & track ) {
2023-12-09 16:23:51 +08:00
if ( ! track ) {
return ;
}
2023-12-09 22:34:22 +08:00
track - > setIndex ( index ) ;
auto & ref = _tracks [ index ] ;
if ( ref . first ) {
WarnL < < " Already existed a same track: " < < index < < " , codec: " < < track - > getCodecName ( ) ;
return ;
2021-06-16 11:39:46 +08:00
}
2023-12-09 22:34:22 +08:00
ref . first = track ;
_sink - > addTrack ( track ) ;
InfoL < < " Got track: " < < track - > getCodecName ( ) ;
_have_video = track - > getTrackType ( ) = = TrackVideo ? true : _have_video ;
2020-05-17 18:00:23 +08:00
}
2023-12-09 22:34:22 +08:00
void DecoderImp : : onFrame ( int index , const Frame : : Ptr & frame ) {
2023-12-09 16:23:51 +08:00
if ( frame ) {
2023-12-09 22:34:22 +08:00
frame - > setIndex ( index ) ;
2023-12-09 16:23:51 +08:00
_sink - > inputFrame ( frame ) ;
}
2020-05-17 18:00:23 +08:00
}
2020-03-06 13:00:06 +08:00
} //namespace mediakit
2020-06-12 18:17:49 +08:00