胡斌

V2.0.10

1.修改一对多布局时,老师视频由多段不同分辨率视频组成时,会出现程序异常的问题
2.一对多布局时,支持对不同分辨率的老师视频进行缩放,统一到相同分辨率
@@ -57,7 +57,7 @@ int CAVDecoder::add(media_info &info) @@ -57,7 +57,7 @@ int CAVDecoder::add(media_info &info)
57 _end_time_ms = info.end_time_ms; 57 _end_time_ms = info.end_time_ms;
58 } 58 }
59 59
60 - av_log(NULL, AV_LOG_INFO, "CAVDecoder add info:%lf, %"PRIu64", %"PRIu64", %.3f\n", _cur_a_ts_ms, _cur_v_ts_ms, _end_time_ms, info.duration); 60 + av_log(NULL, AV_LOG_INFO, "CAVDecoder add info:%lf, %lf, %"PRIu64", %.3f\n", _cur_a_ts_ms, _cur_v_ts_ms, _end_time_ms, info.duration);
61 61
62 return 0; 62 return 0;
63 } 63 }
@@ -104,7 +104,10 @@ _one2one_same_size(one2one_same_size) @@ -104,7 +104,10 @@ _one2one_same_size(one2one_same_size)
104 _pip_width = _scaled_height - pip_x_reduce; //use the scaled height,not the scaled width as pip_width 104 _pip_width = _scaled_height - pip_x_reduce; //use the scaled height,not the scaled width as pip_width
105 _pip_height = _scaled_height - pip_y_reduce; 105 _pip_height = _scaled_height - pip_y_reduce;
106 106
107 - _nOutputHeight = _teacher_height + extent_student_lines * (_pip_height + pip_y_gap) - (part_student == 0 ? (pip_y_gap) : 0); 107 + _nOutputHeight = _teacher_height + extent_student_lines * (_pip_height + pip_y_gap);
  108 + if (extent_student_lines > 0) {
  109 + _nOutputHeight = _nOutputHeight - (part_student == 0 ? (pip_y_gap) : 0);
  110 + }
108 _nOutputHeight = ((_nOutputHeight + 1) / 2) * 2; 111 _nOutputHeight = ((_nOutputHeight + 1) / 2) * 2;
109 112
110 int student_line_width = 4 * (_pip_width)+3 * pip_x_gap + 2 * pip_x_border; 113 int student_line_width = 4 * (_pip_width)+3 * pip_x_gap + 2 * pip_x_border;
@@ -466,17 +469,29 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -466,17 +469,29 @@ int CAVTranscoder::open_output_file(const char *filename)
466 CAVDecoder * pDecoder = decoders_got_frame[idxTeacher]; 469 CAVDecoder * pDecoder = decoders_got_frame[idxTeacher];
467 AVFrame * pFrame = pDecoder->_cur_v_frame; 470 AVFrame * pFrame = pDecoder->_cur_v_frame;
468 if (pFrame) { 471 if (pFrame) {
469 - av_frame_free(&_teacherFrame); 472 + if (_teacherFrame != _scaled_frame_teacher) {
  473 + av_frame_free(&_teacherFrame);
  474 + }
470 _teacherFrame = pFrame; 475 _teacherFrame = pFrame;
471 pDecoder->_cur_v_frame = NULL; 476 pDecoder->_cur_v_frame = NULL;
472 } 477 }
473 } 478 }
474 if (_teacherFrame) { 479 if (_teacherFrame) {
475 - fillDestFrame(pDstFrame, _teacherFrame, 0, 0); 480 + if (_one2one_same_size) {
  481 + fill_one2many_scaled_teacher_frame(pDstFrame);
  482 + }
  483 + else {
  484 + if (_nOutputWidth > _teacherFrame->width) {
  485 + memset(pDstFrame->data[0], _blank_y, pDstFrame->linesize[0] * (_teacherFrame->height));
  486 + memset(pDstFrame->data[1], _blank_u, pDstFrame->linesize[1] * (_teacherFrame->height) / 2);
  487 + memset(pDstFrame->data[2], _blank_v, pDstFrame->linesize[2] * (_teacherFrame->height) / 2);
  488 + }
  489 + fillDestFrame(pDstFrame, _teacherFrame, 0, 0);
  490 + }
476 if (_nOutputHeight > _teacherFrame->height) { 491 if (_nOutputHeight > _teacherFrame->height) {
477 - memset(pDstFrame->data[0] + _teacher_height * pDstFrame->linesize[0], _blank_y, pDstFrame->linesize[0] * (_nOutputHeight - _teacherFrame->height));  
478 - memset(pDstFrame->data[1] + _teacher_height / 2 * pDstFrame->linesize[1], _blank_u, pDstFrame->linesize[1] * (_nOutputHeight - _teacherFrame->height) / 2);  
479 - memset(pDstFrame->data[2] + _teacher_height / 2 * pDstFrame->linesize[2], _blank_v, pDstFrame->linesize[2] * (_nOutputHeight - _teacherFrame->height) / 2); 492 + memset(pDstFrame->data[0] + _teacherFrame->height * pDstFrame->linesize[0], _blank_y, pDstFrame->linesize[0] * (_nOutputHeight - _teacherFrame->height));
  493 + memset(pDstFrame->data[1] + _teacherFrame->height / 2 * pDstFrame->linesize[1], _blank_u, pDstFrame->linesize[1] * (_nOutputHeight - _teacherFrame->height) / 2);
  494 + memset(pDstFrame->data[2] + _teacherFrame->height / 2 * pDstFrame->linesize[2], _blank_v, pDstFrame->linesize[2] * (_nOutputHeight - _teacherFrame->height) / 2);
480 } 495 }
481 } 496 }
482 else 497 else
@@ -901,6 +916,42 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -901,6 +916,42 @@ int CAVTranscoder::open_output_file(const char *filename)
901 } 916 }
902 } 917 }
903 918
  919 + int CAVTranscoder::fill_one2many_scaled_teacher_frame(AVFrame * pDstFrame)
  920 + {
  921 + if (_teacherFrame->width != _teacher_width || _teacherFrame->height != _teacher_height) {
  922 + if (_scaled_frame_teacher != _teacherFrame) {
  923 + if (_src_width_teacher != _teacherFrame->width || _src_height_teacher != _teacherFrame->height) {//init scale context
  924 +
  925 + free_scale_context(&_sws_ctx_teacher, &_scaled_frame_teacher);
  926 +
  927 + int scaled_width, scaled_height;
  928 + get_scaled_dest_size(_teacherFrame, _teacher_width, _teacher_height, &scaled_width, &scaled_height);
  929 + init_scale_context(&_sws_ctx_teacher, &_scaled_frame_teacher, _teacherFrame->width, _teacherFrame->height, scaled_width, scaled_height);
  930 +
  931 + _src_width_teacher = _teacherFrame->width;
  932 + _src_height_teacher = _teacherFrame->height;
  933 + }
  934 +
  935 + int h = 0;
  936 + h = sws_scale(_sws_ctx_teacher, _teacherFrame->data, _teacherFrame->linesize, 0, _teacherFrame->height,
  937 + _scaled_frame_teacher->data, _scaled_frame_teacher->linesize);
  938 + _scaled_frame_teacher->pkt_dts = _teacherFrame->pkt_dts;//pass rotation
  939 +
  940 + av_frame_free(&_teacherFrame);
  941 + _teacherFrame = _scaled_frame_teacher;
  942 + }
  943 + }
  944 +
  945 + if (_nOutputWidth > _teacherFrame->width) {
  946 + memset(pDstFrame->data[0], _blank_y, pDstFrame->linesize[0] * (_teacherFrame->height));
  947 + memset(pDstFrame->data[1], _blank_u, pDstFrame->linesize[1] * (_teacherFrame->height) / 2);
  948 + memset(pDstFrame->data[2], _blank_v, pDstFrame->linesize[2] * (_teacherFrame->height) / 2);
  949 + }
  950 + fillDestFrame(pDstFrame, _teacherFrame, 0, 0);
  951 +
  952 + return 0;
  953 + }
  954 +
904 int CAVTranscoder::mix_and_output_one2one_vframe(vector<CAVDecoder *> & decoders_got_frame) 955 int CAVTranscoder::mix_and_output_one2one_vframe(vector<CAVDecoder *> & decoders_got_frame)
905 { 956 {
906 //prepare one2one base frame 957 //prepare one2one base frame
@@ -81,5 +81,6 @@ private: @@ -81,5 +81,6 @@ private:
81 int scale_fill_one2one_studentframe(AVFrame * pDstFrame, int y); 81 int scale_fill_one2one_studentframe(AVFrame * pDstFrame, int y);
82 int fill_one2one_student_frame(AVFrame * pDstFrame, int y); 82 int fill_one2one_student_frame(AVFrame * pDstFrame, int y);
83 void get_scaled_dest_size(AVFrame * pFrame, int dest_width, int dest_height, int* scaled_width, int* scaled_height); 83 void get_scaled_dest_size(AVFrame * pFrame, int dest_width, int dest_height, int* scaled_width, int* scaled_height);
  84 + int fill_one2many_scaled_teacher_frame(AVFrame * pDstFrame);
84 }; 85 };
85 86
@@ -46,8 +46,8 @@ merge_pip_codec.cfg主要编码参数: @@ -46,8 +46,8 @@ merge_pip_codec.cfg主要编码参数:
46 #音频码率 46 #音频码率
47 a_bit_rate = 64000 47 a_bit_rate = 64000
48 48
49 --s 为可选参数,在一对一布局下起作用。缺省为1  
50 -1 如果老师和学生的视频大小不一致,会放大较小的视频使得老师和学生视频大小相同。 49 +-s 为可选参数。缺省为1
  50 +1 在一对一时, 如果老师和学生的视频大小不一致,会放大较小的视频使得老师和学生视频大小相同。在一对多时,如果老师视频由多段不同分辨率视频组成,会对老师视频进行缩放统一
51 0 保持原有视频大小 51 0 保持原有视频大小
52 52
53 合屏后生成完成信息文件,文件名为"m_" + 输入文件名" + ".txt",合成的mp4文件名为"m_" + 输入文件名" + ".mp4" 53 合屏后生成完成信息文件,文件名为"m_" + 输入文件名" + ".txt",合成的mp4文件名为"m_" + 输入文件名" + ".mp4"
@@ -90,4 +90,8 @@ V2.0.8 @@ -90,4 +90,8 @@ V2.0.8
90 2.修改在一对一布局下,不需要缩放时,学生视频如果宽度小于输出视频宽度,输出视频有部分背景花屏 90 2.修改在一对一布局下,不需要缩放时,学生视频如果宽度小于输出视频宽度,输出视频有部分背景花屏
91 91
92 V2.0.9 92 V2.0.9
93 -1.忽略录像信息文件里在视频文件关闭后设置视频旋转角度的情况,避免视频旋转角度错误  
  93 +1.忽略录像信息文件里在视频文件关闭后设置视频旋转角度的情况,避免视频旋转角度错误
  94 +
  95 +V2.0.10
  96 +1.修改一对多布局时,老师视频由多段不同分辨率视频组成时,会出现程序异常的问题
  97 +2.一对多布局时,支持对不同分辨率的老师视频进行缩放,统一到相同分辨率
@@ -1216,7 +1216,7 @@ int process_av_files(char * record_info, int piptype, bool one2one_same_size, in @@ -1216,7 +1216,7 @@ int process_av_files(char * record_info, int piptype, bool one2one_same_size, in
1216 int main(int argc, char * argv[]) 1216 int main(int argc, char * argv[])
1217 { 1217 {
1218 if (argc < 2) { 1218 if (argc < 2) {
1219 - printf(" merge_pip 2.0.9\n"); 1219 + printf(" merge_pip 2.0.10\n");
1220 printf(" merge video files to one pip video according to record info file,\nusage:"); 1220 printf(" merge video files to one pip video according to record info file,\nusage:");
1221 printf("\n %s record_info_filename [-t {0,1,2}] [-c codec.cfg] [-s {1,0}]", argv[0]); 1221 printf("\n %s record_info_filename [-t {0,1,2}] [-c codec.cfg] [-s {1,0}]", argv[0]);
1222 printf("\n\n"); 1222 printf("\n\n");