V2.0.10
1.修改一对多布局时,老师视频由多段不同分辨率视频组成时,会出现程序异常的问题 2.一对多布局时,支持对不同分辨率的老师视频进行缩放,统一到相同分辨率
正在显示
5 个修改的文件
包含
67 行增加
和
11 行删除
| @@ -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"); |
-
请 注册 或 登录 后发表评论