Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
胡斌
/
merge_av
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
胡斌
2019-05-22 19:52:34 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
a0c88ba21b72dfb2ab05d7e19c2986872b9718f3
a0c88ba2
1 parent
91b5db84
V2.0.6
1. 命令行添加-s可选参数,在一对一布局下起作用。缺省为1 1 如果老师和学生的视频大小不一致,会放大较小的视频使得老师和学生视频大小相同。 0 保持原有视频大小
隐藏空白字符变更
内嵌
并排对比
正在显示
4 个修改的文件
包含
264 行增加
和
73 行删除
pip/AVTranscoder.cpp
pip/AVTranscoder.h
pip/ReadMe.txt
pip/merge_pip.cpp
pip/AVTranscoder.cpp
查看文件 @
a0c88ba
...
...
@@ -31,7 +31,7 @@ int pip_x_border = 4;
#define ensure_no_zero(x, v) if(!x) x = v
CAVTranscoder
::
CAVTranscoder
(
bool
bOne2One
,
int
width_teacher
,
int
height_teacher
,
int
width_student
,
int
height_student
,
bool
has_teacher
,
int
max_audio
)
:
CAVTranscoder
::
CAVTranscoder
(
bool
bOne2One
,
bool
one2one_same_size
,
int
width_teacher
,
int
height_teacher
,
int
width_student
,
int
height_student
,
bool
has_teacher
,
int
max_audio
)
:
_start_time
(
INT64_MAX
),
_all_processed
(
true
),
_nOutputWidth
(
320
),
...
...
@@ -48,7 +48,16 @@ _last_videos_got(-1),
_teacherFrame
(
NULL
),
_studentFrame
(
NULL
),
_pip_width
(
0
),
_pip_height
(
0
)
_pip_height
(
0
),
_sws_ctx_teacher
(
NULL
),
_scaled_frame_teacher
(
NULL
),
_sws_ctx_student
(
NULL
),
_scaled_frame_student
(
NULL
),
_src_width_teacher
(
0
),
_src_height_teacher
(
0
),
_src_width_student
(
0
),
_src_height_student
(
0
),
_one2one_same_size
(
one2one_same_size
)
{
ensure_no_zero
(
width_teacher
,
320
);
ensure_no_zero
(
height_teacher
,
240
);
...
...
@@ -66,6 +75,31 @@ _pip_height(0)
_one2one
=
bOne2One
;
if
(
_one2one
)
{
_nOutputWidth
=
max
(
_teacher_width
,
_student_width
);
if
(
_one2one_same_size
)
{
int
max_width
=
_nOutputWidth
;
int
max_height
=
max
(
_teacher_height
,
_student_height
);
int
min_width
=
min
(
_teacher_width
,
_student_width
);
int
min_height
=
min
(
_teacher_height
,
_student_height
);
if
(
_teacher_width
<
_student_width
)
{
_teacher_width
=
_student_width
;
}
else
if
(
_student_width
<
_teacher_width
)
{
_student_width
=
_teacher_width
;
}
if
(
_teacher_height
<
_student_height
)
{
_teacher_height
=
_student_height
;
}
else
if
(
_student_height
<
_teacher_height
)
{
_student_height
=
_teacher_height
;
}
init_scale_context
(
&
_sws_ctx_w_h
,
&
_scaled_frame_w_h
,
min_width
,
min_height
,
max_width
,
max_height
);
init_scale_context
(
&
_sws_ctx_h_w
,
&
_scaled_frame_h_w
,
min_height
,
min_width
,
max_height
,
max_width
);
init_scale_context
(
&
_sws_ctx_h_h
,
&
_scaled_frame_h_h
,
min_height
,
min_height
,
max_height
,
max_height
);
}
_nOutputHeight
=
_teacher_height
+
_student_height
;
}
else
{
...
...
@@ -180,6 +214,14 @@ int CAVTranscoder::close()
free_scale_context
(
&
_sws_ctx_w_h
,
&
_scaled_frame_w_h
);
free_scale_context
(
&
_sws_ctx_h_w
,
&
_scaled_frame_h_w
);
free_scale_context
(
&
_sws_ctx_h_h
,
&
_scaled_frame_h_h
);
if
(
_scaled_frame_teacher
==
_teacherFrame
)
{
_teacherFrame
=
NULL
;
}
free_scale_context
(
&
_sws_ctx_teacher
,
&
_scaled_frame_teacher
);
if
(
_scaled_frame_student
==
_studentFrame
)
{
_studentFrame
=
NULL
;
}
free_scale_context
(
&
_sws_ctx_student
,
&
_scaled_frame_student
);
#if USE_H264BSF
...
...
@@ -686,6 +728,168 @@ int CAVTranscoder::open_output_file(const char *filename)
return
0
;
}
int
CAVTranscoder
::
scale_fill_one2one_teacherframe
(
AVFrame
*
pDstFrame
)
{
if
(
_src_width_teacher
!=
_teacherFrame
->
width
||
_src_height_teacher
!=
_teacherFrame
->
height
)
{
//init scale context
free_scale_context
(
&
_sws_ctx_teacher
,
&
_scaled_frame_teacher
);
if
(
_teacherFrame
->
width
>=
_teacherFrame
->
height
)
{
init_scale_context
(
&
_sws_ctx_teacher
,
&
_scaled_frame_teacher
,
_teacherFrame
->
width
,
_teacherFrame
->
height
,
_teacher_width
,
_teacher_height
);
}
else
{
init_scale_context
(
&
_sws_ctx_teacher
,
&
_scaled_frame_teacher
,
_teacherFrame
->
height
,
_teacherFrame
->
width
,
_teacher_width
,
_teacher_height
);
}
}
int
h
=
0
;
h
=
sws_scale
(
_sws_ctx_teacher
,
_teacherFrame
->
data
,
_teacherFrame
->
linesize
,
0
,
_teacherFrame
->
height
,
_scaled_frame_teacher
->
data
,
_scaled_frame_teacher
->
linesize
);
_scaled_frame_teacher
->
pkt_dts
=
_teacherFrame
->
pkt_dts
;
//pass rotation
av_frame_free
(
&
_teacherFrame
);
_teacherFrame
=
_scaled_frame_teacher
;
if
(
_teacherFrame
->
width
==
_teacher_width
&&
_teacherFrame
->
height
==
_teacher_height
)
{
if
(
_teacherFrame
->
pkt_dts
!=
90
){
if
(
_teacher_width
<
_nOutputWidth
)
{
memset
(
pDstFrame
->
data
[
0
],
_blank_y
,
pDstFrame
->
linesize
[
0
]
*
_teacher_height
);
memset
(
pDstFrame
->
data
[
1
],
_blank_u
,
pDstFrame
->
linesize
[
1
]
*
_teacher_height
/
2
);
memset
(
pDstFrame
->
data
[
2
],
_blank_v
,
pDstFrame
->
linesize
[
2
]
*
_teacher_height
/
2
);
}
fillDestFrame
(
pDstFrame
,
_teacherFrame
,
0
,
0
);
}
else
{
memset
(
pDstFrame
->
data
[
0
],
_blank_y
,
_nOutputWidth
*
_teacher_height
);
memset
(
pDstFrame
->
data
[
1
],
_blank_u
,
_nOutputWidth
*
_teacher_height
/
2
);
memset
(
pDstFrame
->
data
[
2
],
_blank_v
,
_nOutputWidth
*
_teacher_height
/
2
);
fillDestFrame
(
pDstFrame
,
_teacherFrame
,
(
_nOutputWidth
-
_teacher_height
)
/
2
,
0
,
(
_teacher_width
-
_teacher_height
)
/
2
,
0
,
_teacher_height
,
_teacher_height
);
}
}
else
if
(
_teacherFrame
->
width
==
_teacher_height
&&
_teacherFrame
->
height
==
_teacher_width
)
{
if
(
_teacherFrame
->
pkt_dts
==
90
){
if
(
_teacher_width
<
_nOutputWidth
)
{
memset
(
pDstFrame
->
data
[
0
],
_blank_y
,
pDstFrame
->
linesize
[
0
]
*
_teacher_height
);
memset
(
pDstFrame
->
data
[
1
],
_blank_u
,
pDstFrame
->
linesize
[
1
]
*
_teacher_height
/
2
);
memset
(
pDstFrame
->
data
[
2
],
_blank_v
,
pDstFrame
->
linesize
[
2
]
*
_teacher_height
/
2
);
}
fillDestFrame
(
pDstFrame
,
_teacherFrame
,
0
,
0
);
}
else
{
memset
(
pDstFrame
->
data
[
0
],
_blank_y
,
pDstFrame
->
linesize
[
0
]
*
_teacher_height
);
memset
(
pDstFrame
->
data
[
1
],
_blank_u
,
pDstFrame
->
linesize
[
1
]
*
_teacher_height
/
2
);
memset
(
pDstFrame
->
data
[
2
],
_blank_v
,
pDstFrame
->
linesize
[
2
]
*
_teacher_height
/
2
);
fillDestFrame
(
pDstFrame
,
_teacherFrame
,
(
_nOutputWidth
-
_teacher_height
)
/
2
,
0
,
0
,
(
_teacher_width
-
_teacher_height
)
/
2
,
_teacher_height
,
_teacher_height
);
}
}
else
if
(
_teacherFrame
->
width
==
_teacher_height
&&
_teacherFrame
->
height
==
_teacher_height
)
{
memset
(
pDstFrame
->
data
[
0
],
_blank_y
,
pDstFrame
->
linesize
[
0
]
*
_teacher_height
);
memset
(
pDstFrame
->
data
[
1
],
_blank_u
,
pDstFrame
->
linesize
[
1
]
*
_teacher_height
/
2
);
memset
(
pDstFrame
->
data
[
2
],
_blank_v
,
pDstFrame
->
linesize
[
2
]
*
_teacher_height
/
2
);
fillDestFrame
(
pDstFrame
,
_teacherFrame
,
(
_nOutputWidth
-
_teacher_height
)
/
2
,
0
);
}
return
0
;
}
int
CAVTranscoder
::
scale_fill_one2one_studentframe
(
AVFrame
*
pDstFrame
,
int
y
)
{
if
(
_src_width_student
!=
_studentFrame
->
width
||
_src_height_student
!=
_studentFrame
->
height
)
{
//init scale context
free_scale_context
(
&
_sws_ctx_student
,
&
_scaled_frame_student
);
if
(
_studentFrame
->
width
>=
_studentFrame
->
height
)
{
init_scale_context
(
&
_sws_ctx_student
,
&
_scaled_frame_student
,
_studentFrame
->
width
,
_studentFrame
->
height
,
_student_width
,
_student_height
);
}
else
{
init_scale_context
(
&
_sws_ctx_student
,
&
_scaled_frame_student
,
_studentFrame
->
height
,
_studentFrame
->
width
,
_student_width
,
_student_height
);
}
}
int
h
=
0
;
h
=
sws_scale
(
_sws_ctx_student
,
_studentFrame
->
data
,
_studentFrame
->
linesize
,
0
,
_studentFrame
->
height
,
_scaled_frame_student
->
data
,
_scaled_frame_student
->
linesize
);
_scaled_frame_student
->
pkt_dts
=
_studentFrame
->
pkt_dts
;
//pass rotation
av_frame_free
(
&
_studentFrame
);
_studentFrame
=
_scaled_frame_student
;
if
(
_studentFrame
->
width
==
_student_width
&&
_studentFrame
->
height
==
_student_height
)
{
if
(
_studentFrame
->
pkt_dts
!=
90
){
if
(
_student_width
<
_nOutputWidth
)
{
memset
(
pDstFrame
->
data
[
0
]
+
y
*
pDstFrame
->
linesize
[
0
],
_blank_y
,
pDstFrame
->
linesize
[
0
]
*
_student_height
);
memset
(
pDstFrame
->
data
[
1
]
+
y
*
pDstFrame
->
linesize
[
1
]
/
2
,
_blank_u
,
pDstFrame
->
linesize
[
1
]
*
_student_height
/
2
);
memset
(
pDstFrame
->
data
[
2
]
+
y
*
pDstFrame
->
linesize
[
2
]
/
2
,
_blank_v
,
pDstFrame
->
linesize
[
2
]
*
_student_height
/
2
);
}
fillDestFrame
(
pDstFrame
,
_studentFrame
,
0
,
y
);
}
else
{
memset
(
pDstFrame
->
data
[
0
]
+
y
*
pDstFrame
->
linesize
[
0
],
_blank_y
,
_nOutputWidth
*
_student_height
);
memset
(
pDstFrame
->
data
[
1
]
+
y
*
pDstFrame
->
linesize
[
1
]
/
2
,
_blank_u
,
_nOutputWidth
*
_student_height
/
2
);
memset
(
pDstFrame
->
data
[
2
]
+
y
*
pDstFrame
->
linesize
[
2
]
/
2
,
_blank_v
,
_nOutputWidth
*
_student_height
/
2
);
fillDestFrame
(
pDstFrame
,
_studentFrame
,
(
_nOutputWidth
-
_student_height
)
/
2
,
y
,
(
_student_width
-
_student_height
)
/
2
,
0
,
_student_height
,
_student_height
);
}
}
else
if
(
_studentFrame
->
width
==
_student_height
&&
_studentFrame
->
height
==
_student_width
)
{
if
(
_studentFrame
->
pkt_dts
==
90
){
if
(
_student_width
<
_nOutputWidth
)
{
memset
(
pDstFrame
->
data
[
0
]
+
y
*
pDstFrame
->
linesize
[
0
],
_blank_y
,
pDstFrame
->
linesize
[
0
]
*
_student_height
);
memset
(
pDstFrame
->
data
[
1
]
+
y
*
pDstFrame
->
linesize
[
1
]
/
2
,
_blank_u
,
pDstFrame
->
linesize
[
1
]
*
_student_height
/
2
);
memset
(
pDstFrame
->
data
[
2
]
+
y
*
pDstFrame
->
linesize
[
2
]
/
2
,
_blank_v
,
pDstFrame
->
linesize
[
2
]
*
_student_height
/
2
);
}
fillDestFrame
(
pDstFrame
,
_studentFrame
,
0
,
y
);
}
else
{
memset
(
pDstFrame
->
data
[
0
]
+
y
*
pDstFrame
->
linesize
[
0
],
_blank_y
,
pDstFrame
->
linesize
[
0
]
*
_student_height
);
memset
(
pDstFrame
->
data
[
1
]
+
y
*
pDstFrame
->
linesize
[
1
]
/
2
,
_blank_u
,
pDstFrame
->
linesize
[
1
]
*
_student_height
/
2
);
memset
(
pDstFrame
->
data
[
2
]
+
y
*
pDstFrame
->
linesize
[
2
]
/
2
,
_blank_v
,
pDstFrame
->
linesize
[
2
]
*
_student_height
/
2
);
fillDestFrame
(
pDstFrame
,
_studentFrame
,
(
_nOutputWidth
-
_student_height
)
/
2
,
y
,
0
,
(
_student_width
-
_student_height
)
/
2
,
_student_height
,
_student_height
);
}
}
else
if
(
_studentFrame
->
width
==
_student_height
&&
_studentFrame
->
height
==
_student_height
)
{
memset
(
pDstFrame
->
data
[
0
]
+
y
*
pDstFrame
->
linesize
[
0
],
_blank_y
,
pDstFrame
->
linesize
[
0
]
*
_student_height
);
memset
(
pDstFrame
->
data
[
1
]
+
y
*
pDstFrame
->
linesize
[
1
]
/
2
,
_blank_u
,
pDstFrame
->
linesize
[
1
]
*
_student_height
/
2
);
memset
(
pDstFrame
->
data
[
2
]
+
y
*
pDstFrame
->
linesize
[
2
]
/
2
,
_blank_v
,
pDstFrame
->
linesize
[
2
]
*
_student_height
/
2
);
fillDestFrame
(
pDstFrame
,
_studentFrame
,
(
_nOutputWidth
-
_student_height
)
/
2
,
y
);
}
return
0
;
}
int
CAVTranscoder
::
fill_one2one_student_frame
(
AVFrame
*
pDstFrame
,
int
y
)
{
if
(
_studentFrame
->
width
==
_student_width
&&
_studentFrame
->
height
==
_student_height
)
{
if
(
_studentFrame
->
pkt_dts
!=
90
){
fillDestFrame
(
pDstFrame
,
_studentFrame
,
0
,
y
);
}
else
{
fillDestFrame
(
pDstFrame
,
_studentFrame
,
(
_nOutputWidth
-
_student_height
)
/
2
,
y
,
(
_student_width
-
_student_height
)
/
2
,
0
,
_student_height
,
_student_height
);
}
}
else
if
(
_studentFrame
->
width
==
_student_height
&&
_studentFrame
->
height
==
_student_width
)
{
if
(
_studentFrame
->
pkt_dts
==
90
){
fillDestFrame
(
pDstFrame
,
_studentFrame
,
0
,
y
);
}
else
{
fillDestFrame
(
pDstFrame
,
_studentFrame
,
(
_nOutputWidth
-
_student_height
)
/
2
,
y
,
0
,
(
_student_width
-
_student_height
)
/
2
,
_student_height
,
_student_height
);
}
}
else
if
(
_studentFrame
->
width
==
_student_height
&&
_studentFrame
->
height
==
_student_height
)
{
fillDestFrame
(
pDstFrame
,
_studentFrame
,
(
_nOutputWidth
-
_student_height
)
/
2
,
y
);
}
else
{
if
(
_one2one_same_size
){
scale_fill_one2one_studentframe
(
pDstFrame
,
y
);
}
else
{
//printf("\nresolution: %dx%d unexpected!", _studentFrame->width, _studentFrame->height);
memset
(
pDstFrame
->
data
[
0
]
+
y
*
pDstFrame
->
linesize
[
0
],
_blank_y
,
pDstFrame
->
linesize
[
0
]
*
_teacher_height
);
memset
(
pDstFrame
->
data
[
1
]
+
y
*
pDstFrame
->
linesize
[
1
]
/
2
,
_blank_u
,
pDstFrame
->
linesize
[
1
]
*
_teacher_height
/
2
);
memset
(
pDstFrame
->
data
[
2
]
+
y
*
pDstFrame
->
linesize
[
2
]
/
2
,
_blank_v
,
pDstFrame
->
linesize
[
2
]
*
_teacher_height
/
2
);
fillDestFrame
(
pDstFrame
,
_studentFrame
,
0
,
y
);
}
}
return
0
;
}
int
CAVTranscoder
::
mix_and_output_one2one_vframe
(
vector
<
CAVDecoder
*>
&
decoders_got_frame
)
{
//prepare one2one base frame
...
...
@@ -703,7 +907,9 @@ int CAVTranscoder::open_output_file(const char *filename)
if
(
decoders_got_frame
[
i
]
->
_media_role
==
mr_teacher
)
{
AVFrame
*
pFrame
=
decoders_got_frame
[
i
]
->
_cur_v_frame
;
if
(
pFrame
)
{
av_frame_free
(
&
_teacherFrame
);
if
(
_teacherFrame
!=
_scaled_frame_teacher
)
{
//if is the scaled frame ,don't free it
av_frame_free
(
&
_teacherFrame
);
}
_teacherFrame
=
pFrame
;
decoders_got_frame
[
i
]
->
_cur_v_frame
=
NULL
;
}
...
...
@@ -711,7 +917,9 @@ int CAVTranscoder::open_output_file(const char *filename)
else
{
AVFrame
*
pFrame
=
decoders_got_frame
[
i
]
->
_cur_v_frame
;
if
(
pFrame
)
{
av_frame_free
(
&
_studentFrame
);
if
(
_studentFrame
!=
_scaled_frame_student
)
{
//if is the scaled frame ,don't free it
av_frame_free
(
&
_studentFrame
);
}
_studentFrame
=
pFrame
;
decoders_got_frame
[
i
]
->
_cur_v_frame
=
NULL
;
}
...
...
@@ -765,72 +973,23 @@ int CAVTranscoder::open_output_file(const char *filename)
}
else
{
//printf("\nresolution: %dx%d unexpected!", _teacherFrame->width, _teacherFrame->height);
memset
(
pDstFrame
->
data
[
0
],
_blank_y
,
pDstFrame
->
linesize
[
0
]
*
_teacher_height
);
memset
(
pDstFrame
->
data
[
1
],
_blank_u
,
pDstFrame
->
linesize
[
1
]
*
_teacher_height
/
2
);
memset
(
pDstFrame
->
data
[
2
],
_blank_v
,
pDstFrame
->
linesize
[
2
]
*
_teacher_height
/
2
);
fillDestFrame
(
pDstFrame
,
_teacherFrame
,
0
,
0
);
}
if
(
_studentFrame
)
{
if
(
_studentFrame
->
width
==
_student_width
)
{
if
(
_studentFrame
->
pkt_dts
!=
90
){
if
(
_student_width
<
_nOutputWidth
)
{
memset
(
pDstFrame
->
data
[
0
]
+
_teacher_height
*
pDstFrame
->
linesize
[
0
],
_blank_y
,
pDstFrame
->
linesize
[
0
]
*
_student_height
);
memset
(
pDstFrame
->
data
[
1
]
+
_teacher_height
/
2
*
pDstFrame
->
linesize
[
1
],
_blank_u
,
pDstFrame
->
linesize
[
1
]
*
_student_height
/
2
);
memset
(
pDstFrame
->
data
[
2
]
+
_teacher_height
/
2
*
pDstFrame
->
linesize
[
2
],
_blank_v
,
pDstFrame
->
linesize
[
2
]
*
_student_height
/
2
);
}
fillDestFrame
(
pDstFrame
,
_studentFrame
,
0
,
_teacher_height
);
}
else
{
memset
(
pDstFrame
->
data
[
0
]
+
_teacher_height
*
pDstFrame
->
linesize
[
0
],
_blank_y
,
pDstFrame
->
linesize
[
0
]
*
_student_height
);
memset
(
pDstFrame
->
data
[
1
]
+
_teacher_height
/
2
*
pDstFrame
->
linesize
[
1
],
_blank_u
,
pDstFrame
->
linesize
[
1
]
*
_student_height
/
2
);
memset
(
pDstFrame
->
data
[
2
]
+
_teacher_height
/
2
*
pDstFrame
->
linesize
[
2
],
_blank_v
,
pDstFrame
->
linesize
[
2
]
*
_student_height
/
2
);
fillDestFrame
(
pDstFrame
,
_studentFrame
,
(
_nOutputWidth
-
_student_height
)
/
2
,
_teacher_height
,
(
_student_width
-
_student_height
)
/
2
,
0
,
_student_height
,
_student_height
);
}
}
else
if
(
_studentFrame
->
pkt_dts
==
90
){
if
(
_student_width
<
_nOutputWidth
)
{
memset
(
pDstFrame
->
data
[
0
]
+
_teacher_height
*
pDstFrame
->
linesize
[
0
],
_blank_y
,
pDstFrame
->
linesize
[
0
]
*
_student_height
);
memset
(
pDstFrame
->
data
[
1
]
+
_teacher_height
/
2
*
pDstFrame
->
linesize
[
1
],
_blank_u
,
pDstFrame
->
linesize
[
1
]
*
_student_height
/
2
);
memset
(
pDstFrame
->
data
[
2
]
+
_teacher_height
/
2
*
pDstFrame
->
linesize
[
2
],
_blank_v
,
pDstFrame
->
linesize
[
2
]
*
_student_height
/
2
);
}
fillDestFrame
(
pDstFrame
,
_studentFrame
,
0
,
_teacher_height
);
if
(
!
_one2one_same_size
)
{
memset
(
pDstFrame
->
data
[
0
],
_blank_y
,
pDstFrame
->
linesize
[
0
]
*
_teacher_height
);
memset
(
pDstFrame
->
data
[
1
],
_blank_u
,
pDstFrame
->
linesize
[
1
]
*
_teacher_height
/
2
);
memset
(
pDstFrame
->
data
[
2
],
_blank_v
,
pDstFrame
->
linesize
[
2
]
*
_teacher_height
/
2
);
fillDestFrame
(
pDstFrame
,
_teacherFrame
,
0
,
0
);
}
else
{
memset
(
pDstFrame
->
data
[
0
]
+
_teacher_height
*
pDstFrame
->
linesize
[
0
],
_blank_y
,
pDstFrame
->
linesize
[
0
]
*
_student_height
);
memset
(
pDstFrame
->
data
[
1
]
+
_teacher_height
/
2
*
pDstFrame
->
linesize
[
1
],
_blank_u
,
pDstFrame
->
linesize
[
1
]
*
_student_height
/
2
);
memset
(
pDstFrame
->
data
[
2
]
+
_teacher_height
/
2
*
pDstFrame
->
linesize
[
2
],
_blank_v
,
pDstFrame
->
linesize
[
2
]
*
_student_height
/
2
);
fillDestFrame
(
pDstFrame
,
_studentFrame
,
(
_nOutputWidth
-
_student_height
)
/
2
,
_teacher_height
,
0
,
(
_student_width
-
_student_height
)
/
2
,
_student_height
,
_student_height
);
scale_fill_one2one_teacherframe
(
pDstFrame
);
}
}
if
(
_studentFrame
)
{
fill_one2one_student_frame
(
pDstFrame
,
_teacher_height
);
}
}
else
if
(
_studentFrame
)
{
if
(
_studentFrame
->
width
==
_student_width
&&
_studentFrame
->
height
==
_student_height
)
{
if
(
_studentFrame
->
pkt_dts
!=
90
){
fillDestFrame
(
pDstFrame
,
_studentFrame
,
0
,
0
);
}
else
{
fillDestFrame
(
pDstFrame
,
_studentFrame
,
(
_nOutputWidth
-
_student_height
)
/
2
,
0
,
(
_student_width
-
_student_height
)
/
2
,
0
,
_student_height
,
_student_height
);
}
}
else
if
(
_studentFrame
->
width
==
_student_height
&&
_studentFrame
->
height
==
_student_width
)
{
if
(
_studentFrame
->
pkt_dts
==
90
){
fillDestFrame
(
pDstFrame
,
_studentFrame
,
0
,
0
);
}
else
{
fillDestFrame
(
pDstFrame
,
_studentFrame
,
(
_nOutputWidth
-
_student_height
)
/
2
,
0
,
0
,
(
_student_width
-
_student_height
)
/
2
,
_student_height
,
_student_height
);
}
}
else
if
(
_studentFrame
->
width
==
_student_height
&&
_studentFrame
->
height
==
_student_height
)
{
fillDestFrame
(
pDstFrame
,
_studentFrame
,
(
_nOutputWidth
-
_student_height
)
/
2
,
0
);
}
else
{
//printf("\nresolution: %dx%d unexpected!", _studentFrame->width, _studentFrame->height);
memset
(
pDstFrame
->
data
[
0
],
_blank_y
,
pDstFrame
->
linesize
[
0
]
*
_teacher_height
);
memset
(
pDstFrame
->
data
[
1
],
_blank_u
,
pDstFrame
->
linesize
[
1
]
*
_teacher_height
/
2
);
memset
(
pDstFrame
->
data
[
2
],
_blank_v
,
pDstFrame
->
linesize
[
2
]
*
_teacher_height
/
2
);
fillDestFrame
(
pDstFrame
,
_studentFrame
,
0
,
0
);
}
fill_one2one_student_frame
(
pDstFrame
,
0
);
}
if
(
decoders_got_frame
.
size
()
==
2
){
...
...
pip/AVTranscoder.h
查看文件 @
a0c88ba
...
...
@@ -5,7 +5,7 @@
class
CAVTranscoder
{
public
:
CAVTranscoder
(
bool
bOne2One
,
int
width_teacher
,
int
height_teacher
,
int
student_width
,
int
student_height
,
bool
has_teacher
,
int
max_audio
);
CAVTranscoder
(
bool
bOne2One
,
bool
one2one_same_size
,
int
width_teacher
,
int
height_teacher
,
int
student_width
,
int
student_height
,
bool
has_teacher
,
int
max_audio
);
virtual
~
CAVTranscoder
();
int
add
(
media_info
&
info
);
...
...
@@ -34,6 +34,7 @@ private:
int
mix_and_output_one2one_vframe
(
vector
<
CAVDecoder
*>
&
decoders_got_frame
);
int
mix_and_output_one2many_vframe
(
vector
<
CAVDecoder
*>
&
decoders_got_frame
);
int
scale_fill_one2one_teacherframe
(
AVFrame
*
pDstFrame
);
int
fillDestFrame
(
AVFrame
*
pDstFrame
,
AVFrame
*
pSrcFrame
,
int
x
,
int
y
);
int
fillDestFrame
(
AVFrame
*
pDstFrame
,
AVFrame
*
pSrcFrame
,
int
destx
,
int
desty
,
int
srcx
,
int
srcy
,
int
w
,
int
h
);
int
encode_write_frame
(
AVFrame
*
filt_frame
,
unsigned
int
stream_index
,
int
*
got_frame
);
...
...
@@ -52,18 +53,32 @@ private:
int
_teacher_height
;
int
_student_width
;
int
_student_height
;
struct
SwsContext
*
_sws_ctx_w_h
;
bool
_one2one_same_size
;
//top and bottom are same size ,if not ,scale the smaller to the larger
struct
SwsContext
*
_sws_ctx_w_h
;
//for one2many student frame
struct
SwsContext
*
_sws_ctx_h_w
;
struct
SwsContext
*
_sws_ctx_h_h
;
AVFrame
*
_scaled_frame_w_h
;
AVFrame
*
_scaled_frame_h_w
;
AVFrame
*
_scaled_frame_h_h
;
int
_last_videos_got
;
AVFrame
*
_teacherFrame
;
AVFrame
*
_studentFrame
;
// for one2one,keep the last frame
struct
SwsContext
*
_sws_ctx_teacher
;
//for one2one teacher frame
AVFrame
*
_scaled_frame_teacher
;
int
_src_width_teacher
;
int
_src_height_teacher
;
struct
SwsContext
*
_sws_ctx_student
;
//for one2one teacher frame
AVFrame
*
_scaled_frame_student
;
int
_src_width_student
;
int
_src_height_student
;
uint8_t
_blank_y
,
_blank_u
,
_blank_v
;
public
:
void
set_max_audio
(
int
max_audio
);
private
:
int
scale_fill_one2one_studentframe
(
AVFrame
*
pDstFrame
,
int
y
);
int
fill_one2one_student_frame
(
AVFrame
*
pDstFrame
,
int
y
);
};
...
...
pip/ReadMe.txt
查看文件 @
a0c88ba
...
...
@@ -3,7 +3,7 @@
读入合屏信息文件,合成画中画视频。
使用方法:
merge_pip merge_info.txt [-t {0,1,2}] [-c codec.cfg]
merge_pip merge_info.txt [-t {0,1,2}] [-c codec.cfg]
[-s {1,0}]
其中merge_info.txt为合屏信息文件,格式如下:
teacher:
...
...
@@ -46,6 +46,9 @@ merge_pip_codec.cfg主要编码参数:
#音频码率
a_bit_rate = 64000
-s 为可选参数,在一对一布局下起作用。缺省为1
1 如果老师和学生的视频大小不一致,会放大较小的视频使得老师和学生视频大小相同。
0 保持原有视频大小
合屏后生成完成信息文件,文件名为"m_" + 输入文件名" + ".txt",合成的mp4文件名为"m_" + 输入文件名" + ".mp4"
如merge_pip 1.txt
...
...
@@ -71,4 +74,9 @@ V2.0.4
1.支持读取编码配置文件,用于改变编码配置
V2.0.5
1.在录像信息文件里没有老师视频或学生视频时,把老师视频或学生视频的大小设为320x240,避免在一对多布局时出现错误
\ No newline at end of file
1.在录像信息文件里没有老师视频或学生视频时,把老师视频或学生视频的大小设为320x240,避免在一对多布局时出现错误
V2.0.6
1. 命令行添加-s可选参数,在一对一布局下起作用。缺省为1
1 如果老师和学生的视频大小不一致,会放大较小的视频使得老师和学生视频大小相同。
0 保持原有视频大小
\ No newline at end of file
...
...
pip/merge_pip.cpp
查看文件 @
a0c88ba
...
...
@@ -1088,7 +1088,7 @@ int load_record_info(char * record_info)
#define MIN_TIME_INTERVAL 25
int
process_av_files
(
char
*
record_info
,
int
piptype
)
int
process_av_files
(
char
*
record_info
,
int
piptype
,
bool
one2one_same_size
)
{
time_t
start
,
end
;
time
(
&
start
);
...
...
@@ -1127,7 +1127,7 @@ int process_av_files(char * record_info, int piptype)
}
}
CAVTranscoder
videoTranscoder
(
one2one
,
width_teacher
,
height_teacher
,
width_student
,
height_student
,
has_teacher
,
max_audio
);
CAVTranscoder
videoTranscoder
(
one2one
,
one2one_same_size
,
width_teacher
,
height_teacher
,
width_student
,
height_student
,
has_teacher
,
max_audio
);
videoTranscoder
.
set_max_audio
(
max_audio
);
int64_t
cur_time
=
0
;
...
...
@@ -1202,14 +1202,15 @@ int process_av_files(char * record_info, int piptype)
int
main
(
int
argc
,
char
*
argv
[])
{
if
(
argc
<
2
)
{
printf
(
" merge_pip 2.0.
5
\n
"
);
printf
(
" merge_pip 2.0.
6
\n
"
);
printf
(
" merge video files to one pip video according to record info file,
\n
usage:"
);
printf
(
"
\n
%s record_info_filename [-t {0,1,2}] [-c codec.cfg]"
,
argv
[
0
]);
printf
(
"
\n
%s record_info_filename [-t {0,1,2}] [-c codec.cfg]
[-s {1,0}]
"
,
argv
[
0
]);
printf
(
"
\n\n
"
);
return
-
1
;
}
int
piptype
=
0
;
bool
one2one_same_size
=
true
;
for
(
int
i
=
2
;
i
<
argc
;
i
++
){
if
(
!
strcmp
(
argv
[
i
],
"-t"
)){
i
++
;
...
...
@@ -1227,6 +1228,14 @@ int main(int argc, char * argv[])
}
strcpy
(
user_codec_cfg
,
argv
[
i
]);
}
else
if
(
!
strcmp
(
argv
[
i
],
"-s"
)){
i
++
;
if
(
i
>
argc
)
{
printf
(
"error,should be 1 or 0 after -s"
);
return
-
2
;
}
one2one_same_size
=
argv
[
i
][
0
]
==
'1'
;
}
}
...
...
@@ -1234,5 +1243,5 @@ int main(int argc, char * argv[])
load_codec_param
();
return
process_av_files
(
argv
[
1
],
piptype
);
return
process_av_files
(
argv
[
1
],
piptype
,
one2one_same_size
);
}
...
...
请
注册
或
登录
后发表评论