Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Z
ZLMediaKit
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
张翔宇
ZLMediaKit
Commits
72c2df05
Commit
72c2df05
authored
Sep 02, 2021
by
ziyue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
改成异步解码,并修复内存泄露问题
parent
895dc04f
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
55 行增加
和
24 行删除
+55
-24
player/FFMpegDecoder.cpp
+0
-0
player/FFMpegDecoder.h
+43
-17
player/test_player.cpp
+12
-7
没有找到文件。
player/FFMpegDecoder.cpp
查看文件 @
72c2df05
差异被折叠。
点击展开。
player/FFMpegDecoder.h
查看文件 @
72c2df05
...
...
@@ -10,11 +10,9 @@
#ifndef FFMpegDecoder_H_
#define FFMpegDecoder_H_
#include <string>
#include <memory>
#include <stdexcept>
#include "Extension/Frame.h"
#include "Extension/Track.h"
#include "Util/TimeTicker.h"
#include "Common/MediaSink.h"
#ifdef __cplusplus
extern
"C"
{
...
...
@@ -25,9 +23,6 @@ extern "C" {
}
#endif
using
namespace
std
;
using
namespace
mediakit
;
class
FFmpegFrame
{
public
:
using
Ptr
=
std
::
shared_ptr
<
FFmpegFrame
>
;
...
...
@@ -36,14 +31,13 @@ public:
~
FFmpegFrame
();
AVFrame
*
get
()
const
;
void
fillPicture
(
AVPixelFormat
target_format
,
int
target_width
,
int
target_height
);
private
:
char
*
_data
=
nullptr
;
std
::
shared_ptr
<
AVFrame
>
_frame
;
};
class
FFmpegSwr
{
class
FFmpegSwr
{
public
:
using
Ptr
=
std
::
shared_ptr
<
FFmpegSwr
>
;
...
...
@@ -58,33 +52,65 @@ private:
int
_target_samplerate
;
AVSampleFormat
_target_format
;
SwrContext
*
_ctx
=
nullptr
;
ResourcePool
<
FFmpegFrame
>
_frame_pool
;
};
class
FFmpegDecoder
:
public
FrameWriterInterface
{
class
TaskManager
{
public
:
TaskManager
()
=
default
;
~
TaskManager
();
protected
:
void
startThread
(
const
string
&
name
);
void
stopThread
();
void
addEncodeTask
(
function
<
void
()
>
task
);
void
addDecodeTask
(
bool
key_frame
,
function
<
void
()
>
task
);
bool
isEnabled
()
const
;
private
:
void
onThreadRun
(
const
string
&
name
);
void
pushExit
();
private
:
class
ThreadExitException
:
public
std
::
runtime_error
{
public
:
ThreadExitException
()
:
std
::
runtime_error
(
"exit"
)
{}
~
ThreadExitException
()
=
default
;
};
private
:
bool
_decode_drop_start
=
false
;
bool
_exit
=
false
;
mutex
_task_mtx
;
semaphore
_sem
;
List
<
function
<
void
()
>
>
_task
;
std
::
shared_ptr
<
thread
>
_thread
;
};
class
FFmpegDecoder
:
public
FrameWriterInterface
,
private
TaskManager
{
public
:
using
Ptr
=
std
::
shared_ptr
<
FFmpegDecoder
>
;
using
onDec
=
function
<
void
(
const
FFmpegFrame
::
Ptr
&
)
>
;
FFmpegDecoder
(
const
Track
::
Ptr
&
track
);
~
FFmpegDecoder
()
{}
~
FFmpegDecoder
()
;
void
inputFrame
(
const
Frame
::
Ptr
&
frame
)
override
;
void
inputFrame
(
const
char
*
data
,
size_t
size
,
uint32_t
dts
,
uint32_t
pts
);
void
setOnDecode
(
onDec
cb
);
void
flush
();
const
AVCodecContext
*
getContext
()
const
;
private
:
void
onDecode
(
const
FFmpegFrame
::
Ptr
&
frame
);
void
inputFrame_l
(
const
Frame
::
Ptr
&
frame
);
void
decodeFrame
(
const
char
*
data
,
size_t
size
,
uint32_t
dts
,
uint32_t
pts
);
private
:
bool
_do_merger
=
false
;
Ticker
_ticker
;
onDec
_cb
;
FFmpegSwr
::
Ptr
_swr
;
ResourcePool
<
FFmpegFrame
>
_frame_pool
;
std
::
shared_ptr
<
AVCodecContext
>
_context
;
FrameMerger
_merger
{
FrameMerger
::
h264_prefix
};
};
#endif
/* FFMpegDecoder_H_ */
...
...
player/test_player.cpp
查看文件 @
72c2df05
...
...
@@ -83,11 +83,8 @@ int main(int argc, char *argv[]) {
return
true
;
});
});
auto
merger
=
std
::
make_shared
<
FrameMerger
>
(
FrameMerger
::
h264_prefix
);
auto
delegate
=
std
::
make_shared
<
FrameWriterInterfaceHelper
>
([
decoder
,
merger
](
const
Frame
::
Ptr
&
frame
)
{
merger
->
inputFrame
(
frame
,
[
&
](
uint32_t
dts
,
uint32_t
pts
,
const
Buffer
::
Ptr
&
buffer
,
bool
have_idr
)
{
decoder
->
inputFrame
(
buffer
->
data
(),
buffer
->
size
(),
dts
,
pts
);
});
auto
delegate
=
std
::
make_shared
<
FrameWriterInterfaceHelper
>
([
decoder
](
const
Frame
::
Ptr
&
frame
)
{
decoder
->
inputFrame
(
frame
);
});
videoTrack
->
addDelegate
(
delegate
);
}
...
...
@@ -97,8 +94,16 @@ int main(int argc, char *argv[]) {
auto
audio_player
=
std
::
make_shared
<
AudioPlayer
>
();
//FFmpeg解码时已经统一转换为16位整型pcm
audio_player
->
setup
(
audioTrack
->
getAudioSampleRate
(),
audioTrack
->
getAudioChannel
(),
AUDIO_S16
);
decoder
->
setOnDecode
([
audio_player
](
const
FFmpegFrame
::
Ptr
&
pcm
)
{
audio_player
->
playPCM
((
const
char
*
)
(
pcm
->
get
()
->
data
[
0
]),
pcm
->
get
()
->
linesize
[
0
]);
FFmpegSwr
::
Ptr
swr
;
decoder
->
setOnDecode
([
audio_player
,
swr
](
const
FFmpegFrame
::
Ptr
&
frame
)
mutable
{
if
(
!
swr
)
{
swr
=
std
::
make_shared
<
FFmpegSwr
>
(
AV_SAMPLE_FMT_S16
,
frame
->
get
()
->
channels
,
frame
->
get
()
->
channel_layout
,
frame
->
get
()
->
sample_rate
);
}
auto
pcm
=
swr
->
inputFrame
(
frame
);
auto
len
=
pcm
->
get
()
->
nb_samples
*
pcm
->
get
()
->
channels
*
av_get_bytes_per_sample
((
enum
AVSampleFormat
)
pcm
->
get
()
->
format
);
audio_player
->
playPCM
((
const
char
*
)
(
pcm
->
get
()
->
data
[
0
]),
len
);
});
auto
audio_delegate
=
std
::
make_shared
<
FrameWriterInterfaceHelper
>
(
[
decoder
](
const
Frame
::
Ptr
&
frame
)
{
decoder
->
inputFrame
(
frame
);
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论