keep last frame in same av segment,need improved
save output info
正在显示
6 个修改的文件
包含
83 行增加
和
41 行删除
| @@ -16,6 +16,8 @@ _media_role(mr_student) | @@ -16,6 +16,8 @@ _media_role(mr_student) | ||
| 16 | 16 | ||
| 17 | CAVDecoder::~CAVDecoder() | 17 | CAVDecoder::~CAVDecoder() |
| 18 | { | 18 | { |
| 19 | + free_cur_v_frame(); | ||
| 20 | + free_cur_a_frame(); | ||
| 19 | } | 21 | } |
| 20 | 22 | ||
| 21 | int CAVDecoder::add(media_info &info) | 23 | int CAVDecoder::add(media_info &info) |
| @@ -59,9 +61,13 @@ bool CAVDecoder::get_one_v_frame() | @@ -59,9 +61,13 @@ bool CAVDecoder::get_one_v_frame() | ||
| 59 | int64_t ts; | 61 | int64_t ts; |
| 60 | int ret = -1; | 62 | int ret = -1; |
| 61 | if (_video_info.size()) { | 63 | if (_video_info.size()) { |
| 62 | - ret = _video_decoder.get_one_frame(&_cur_v_frame, ts); | 64 | + AVFrame * pFrame = NULL; |
| 65 | + ret = _video_decoder.get_one_frame(&pFrame, ts); | ||
| 63 | if (ret == 0) { | 66 | if (ret == 0) { |
| 64 | - //_cur_v_ts_ms = _v_start_time_ms + ts; | 67 | + if (pFrame){ |
| 68 | + free_cur_v_frame(); | ||
| 69 | + _cur_v_frame = pFrame; | ||
| 70 | + } | ||
| 65 | _cur_v_ts_ms += VFRAME_DURATION_MS; | 71 | _cur_v_ts_ms += VFRAME_DURATION_MS; |
| 66 | } | 72 | } |
| 67 | else { | 73 | else { |
| @@ -77,23 +83,30 @@ bool CAVDecoder::get_one_v_frame() | @@ -77,23 +83,30 @@ bool CAVDecoder::get_one_v_frame() | ||
| 77 | if (_cur_v_ts_ms < _end_time_ms) {//should have as video frame | 83 | if (_cur_v_ts_ms < _end_time_ms) {//should have as video frame |
| 78 | _cur_v_ts_ms += VFRAME_DURATION_MS;//return last v frame | 84 | _cur_v_ts_ms += VFRAME_DURATION_MS;//return last v frame |
| 79 | ret = 0; | 85 | ret = 0; |
| 80 | - if (!_cur_v_frame) { | ||
| 81 | - _cur_v_frame = get_blank_frame(); | ||
| 82 | - } | ||
| 83 | } | 86 | } |
| 84 | } | 87 | } |
| 85 | 88 | ||
| 86 | return ret == 0; | 89 | return ret == 0; |
| 87 | } | 90 | } |
| 88 | 91 | ||
| 89 | -AVFrame * CAVDecoder::get_blank_frame() | 92 | +std::string CAVDecoder::get_cur_vfile() |
| 90 | { | 93 | { |
| 91 | - return NULL; | 94 | + if (_video_info.size()){ |
| 95 | + return _video_info.front().name; | ||
| 96 | + } | ||
| 97 | + else { | ||
| 98 | + return ""; | ||
| 99 | + } | ||
| 92 | } | 100 | } |
| 93 | 101 | ||
| 94 | -AVFrame * CAVDecoder::get_silence_frame() | 102 | +std::string CAVDecoder::get_cur_afile() |
| 95 | { | 103 | { |
| 96 | - return NULL; | 104 | + if (_audio_info.size()){ |
| 105 | + return _audio_info.front().name; | ||
| 106 | + } | ||
| 107 | + else { | ||
| 108 | + return ""; | ||
| 109 | + } | ||
| 97 | } | 110 | } |
| 98 | 111 | ||
| 99 | void CAVDecoder::free_cur_a_frame() | 112 | void CAVDecoder::free_cur_a_frame() |
| @@ -114,6 +127,7 @@ bool CAVDecoder::get_one_a_frame() | @@ -114,6 +127,7 @@ bool CAVDecoder::get_one_a_frame() | ||
| 114 | { | 127 | { |
| 115 | int64_t ts; | 128 | int64_t ts; |
| 116 | int ret = -1; | 129 | int ret = -1; |
| 130 | + free_cur_a_frame(); | ||
| 117 | if (_audio_info.size()) { | 131 | if (_audio_info.size()) { |
| 118 | ret = _audio_decoder.get_one_frame(&_cur_a_frame, ts); | 132 | ret = _audio_decoder.get_one_frame(&_cur_a_frame, ts); |
| 119 | if (ret == 0) { | 133 | if (ret == 0) { |
| @@ -132,9 +146,6 @@ bool CAVDecoder::get_one_a_frame() | @@ -132,9 +146,6 @@ bool CAVDecoder::get_one_a_frame() | ||
| 132 | if (_cur_a_ts_ms < _end_time_ms) {//should have a audio frame | 146 | if (_cur_a_ts_ms < _end_time_ms) {//should have a audio frame |
| 133 | _cur_a_ts_ms += AFRAME_DURATION_MS;//return last a frame | 147 | _cur_a_ts_ms += AFRAME_DURATION_MS;//return last a frame |
| 134 | ret = 0; | 148 | ret = 0; |
| 135 | - if (!_cur_a_frame) { | ||
| 136 | - _cur_a_frame = get_silence_frame(); | ||
| 137 | - } | ||
| 138 | } | 149 | } |
| 139 | } | 150 | } |
| 140 | 151 |
| @@ -13,6 +13,8 @@ public: | @@ -13,6 +13,8 @@ public: | ||
| 13 | unsigned int getuid(); | 13 | unsigned int getuid(); |
| 14 | bool get_one_a_frame(); | 14 | bool get_one_a_frame(); |
| 15 | bool get_one_v_frame(); | 15 | bool get_one_v_frame(); |
| 16 | + std::string get_cur_vfile(); | ||
| 17 | + std::string get_cur_afile(); | ||
| 16 | double _cur_a_ts_ms; | 18 | double _cur_a_ts_ms; |
| 17 | int64_t _cur_v_ts_ms; | 19 | int64_t _cur_v_ts_ms; |
| 18 | media_role _media_role; | 20 | media_role _media_role; |
| @@ -31,11 +33,9 @@ protected: | @@ -31,11 +33,9 @@ protected: | ||
| 31 | int64_t _end_time_ms; | 33 | int64_t _end_time_ms; |
| 32 | unsigned int _uid; | 34 | unsigned int _uid; |
| 33 | 35 | ||
| 34 | -private: | ||
| 35 | - AVFrame * get_blank_frame(); | ||
| 36 | - AVFrame * get_silence_frame(); | ||
| 37 | -public: | ||
| 38 | - void free_cur_a_frame(); | 36 | + |
| 37 | +protected: | ||
| 39 | void free_cur_v_frame(); | 38 | void free_cur_v_frame(); |
| 39 | + void free_cur_a_frame(); | ||
| 40 | }; | 40 | }; |
| 41 | 41 |
| @@ -19,7 +19,8 @@ _cur_out_v_ts(0), | @@ -19,7 +19,8 @@ _cur_out_v_ts(0), | ||
| 19 | _cur_out_a_ts(0), | 19 | _cur_out_a_ts(0), |
| 20 | _max_audio(1), | 20 | _max_audio(1), |
| 21 | _swsCtx(NULL), | 21 | _swsCtx(NULL), |
| 22 | -_scaledFrame(NULL) | 22 | +_scaledFrame(NULL), |
| 23 | +_last_videos_got(-1) | ||
| 23 | { | 24 | { |
| 24 | _one2one = bOne2One; | 25 | _one2one = bOne2One; |
| 25 | if (_one2one) { | 26 | if (_one2one) { |
| @@ -237,7 +238,7 @@ int CAVTranscoder::open_output_file(const char *filename) | @@ -237,7 +238,7 @@ int CAVTranscoder::open_output_file(const char *filename) | ||
| 237 | /* Third parameter can be used to pass settings to encoder */ | 238 | /* Third parameter can be used to pass settings to encoder */ |
| 238 | ret = avcodec_open2(enc_ctx, encoder, NULL); | 239 | ret = avcodec_open2(enc_ctx, encoder, NULL); |
| 239 | if (ret < 0) { | 240 | if (ret < 0) { |
| 240 | - av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n", i); | 241 | + av_log(NULL, AV_LOG_ERROR, "Cannot open audio encoder for stream #%u\n", i); |
| 241 | return ret; | 242 | return ret; |
| 242 | } | 243 | } |
| 243 | } | 244 | } |
| @@ -299,7 +300,6 @@ int CAVTranscoder::open_output_file(const char *filename) | @@ -299,7 +300,6 @@ int CAVTranscoder::open_output_file(const char *filename) | ||
| 299 | for (int i = 0; i < 1024; i++,pdst++,psrc++) { | 300 | for (int i = 0; i < 1024; i++,pdst++,psrc++) { |
| 300 | *pdst += (*psrc/_max_audio); | 301 | *pdst += (*psrc/_max_audio); |
| 301 | } | 302 | } |
| 302 | - (*it)->free_cur_a_frame(); | ||
| 303 | } | 303 | } |
| 304 | } | 304 | } |
| 305 | 305 | ||
| @@ -339,7 +339,6 @@ int CAVTranscoder::open_output_file(const char *filename) | @@ -339,7 +339,6 @@ int CAVTranscoder::open_output_file(const char *filename) | ||
| 339 | if (pFrame) { | 339 | if (pFrame) { |
| 340 | fillDestFrame(pDstFrame, pFrame, 0, 0); | 340 | fillDestFrame(pDstFrame, pFrame, 0, 0); |
| 341 | fill_pure_color = false; | 341 | fill_pure_color = false; |
| 342 | - pDecoder->free_cur_v_frame(); | ||
| 343 | } | 342 | } |
| 344 | } | 343 | } |
| 345 | if(fill_pure_color){//fill with pure color | 344 | if(fill_pure_color){//fill with pure color |
| @@ -364,8 +363,7 @@ int CAVTranscoder::open_output_file(const char *filename) | @@ -364,8 +363,7 @@ int CAVTranscoder::open_output_file(const char *filename) | ||
| 364 | } | 363 | } |
| 365 | 364 | ||
| 366 | //copy each frame to the dest frame | 365 | //copy each frame to the dest frame |
| 367 | - fillDestFrame(pDstFrame, _scaledFrame, SRC_W - SCALED_H - ((imageIdx % 4) * SCALED_H), SRC_H - SCALED_H - (SCALED_H + 8)*imageIdx / 4, (SCALED_W - SCALED_H) / 2, 0, SCALED_H, SCALED_H); | ||
| 368 | - pDecoder->free_cur_v_frame(); | 366 | + fillDestFrame(pDstFrame, _scaledFrame, SRC_W - SCALED_H - 10 - (imageIdx % 4) * (SCALED_H + 10), SRC_H - SCALED_H - (SCALED_H + 8)*(imageIdx / 4), (SCALED_W - SCALED_H) / 2, 0, SCALED_H, SCALED_H); |
| 369 | imageIdx++; | 367 | imageIdx++; |
| 370 | } | 368 | } |
| 371 | } | 369 | } |
| @@ -427,21 +425,35 @@ int CAVTranscoder::open_output_file(const char *filename) | @@ -427,21 +425,35 @@ int CAVTranscoder::open_output_file(const char *filename) | ||
| 427 | memset(dstbuf, 0x80, nDstSize); | 425 | memset(dstbuf, 0x80, nDstSize); |
| 428 | 426 | ||
| 429 | if (decoders_got_frame.size() == 2){ | 427 | if (decoders_got_frame.size() == 2){ |
| 428 | + if (_last_videos_got != 2) { | ||
| 429 | + _last_videos_got = 2; | ||
| 430 | + printf("\n--get 2 video:%"PRIu64", %s, %s\n", _cur_out_v_ts, decoders_got_frame[0]->get_cur_vfile().c_str(), decoders_got_frame[1]->get_cur_vfile().c_str()); | ||
| 431 | + } | ||
| 430 | fillDestFrame(pDstFrame, decoders_got_frame[0]->_cur_v_frame, 0, decoders_got_frame[0]->_media_role == mr_teacher ? 0 : 240); | 432 | fillDestFrame(pDstFrame, decoders_got_frame[0]->_cur_v_frame, 0, decoders_got_frame[0]->_media_role == mr_teacher ? 0 : 240); |
| 431 | - decoders_got_frame[0]->free_cur_v_frame(); | 433 | + |
| 432 | fillDestFrame(pDstFrame, decoders_got_frame[1]->_cur_v_frame, 0, decoders_got_frame[1]->_media_role == mr_teacher ? 0 : 240); | 434 | fillDestFrame(pDstFrame, decoders_got_frame[1]->_cur_v_frame, 0, decoders_got_frame[1]->_media_role == mr_teacher ? 0 : 240); |
| 433 | - decoders_got_frame[1]->free_cur_v_frame(); | ||
| 434 | } | 435 | } |
| 435 | else if (decoders_got_frame.size() == 1) | 436 | else if (decoders_got_frame.size() == 1) |
| 436 | { | 437 | { |
| 438 | + if (_last_videos_got != 1) { | ||
| 439 | + _last_videos_got = 1; | ||
| 440 | + printf("\n--get 1 video:%"PRIu64", %s\n", _cur_out_v_ts, decoders_got_frame[0]->get_cur_vfile().c_str()); | ||
| 441 | + } | ||
| 437 | fillDestFrame(pDstFrame, decoders_got_frame[0]->_cur_v_frame, 0, 0); | 442 | fillDestFrame(pDstFrame, decoders_got_frame[0]->_cur_v_frame, 0, 0); |
| 438 | - decoders_got_frame[0]->free_cur_v_frame(); | ||
| 439 | //todo: fill the bottom half image with pure color | 443 | //todo: fill the bottom half image with pure color |
| 440 | } | 444 | } |
| 441 | else { | 445 | else { |
| 446 | + if (_last_videos_got != 0) { | ||
| 447 | + _last_videos_got = 0; | ||
| 448 | + printf("\n--get 0 video:%"PRIu64"\n", _cur_out_v_ts); | ||
| 449 | + } | ||
| 442 | //fill with last image? | 450 | //fill with last image? |
| 443 | } | 451 | } |
| 444 | - | 452 | +#if 0 |
| 453 | + if (_cur_out_v_ts > (26 * 60 + 57) *(1000 /50)) { | ||
| 454 | + printf("\n--get %d video:%"PRIu64"\n", decoders_got_frame.size(), _cur_out_v_ts); | ||
| 455 | + } | ||
| 456 | +#endif | ||
| 445 | //fill the timestamp of dest frame | 457 | //fill the timestamp of dest frame |
| 446 | 458 | ||
| 447 | pDstFrame->pts = _cur_out_v_ts; | 459 | pDstFrame->pts = _cur_out_v_ts; |
| @@ -43,6 +43,7 @@ private: | @@ -43,6 +43,7 @@ private: | ||
| 43 | int _max_audio; | 43 | int _max_audio; |
| 44 | struct SwsContext * _swsCtx; | 44 | struct SwsContext * _swsCtx; |
| 45 | AVFrame * _scaledFrame; | 45 | AVFrame * _scaledFrame; |
| 46 | + int _last_videos_got; | ||
| 46 | public: | 47 | public: |
| 47 | void set_max_audio(int max_audio); | 48 | void set_max_audio(int max_audio); |
| 48 | }; | 49 | }; |
| @@ -23,6 +23,15 @@ int CVideoDecoder::add(media_info &info) | @@ -23,6 +23,15 @@ int CVideoDecoder::add(media_info &info) | ||
| 23 | _info.push_back(info); | 23 | _info.push_back(info); |
| 24 | _rotate = info.rotate; | 24 | _rotate = info.rotate; |
| 25 | 25 | ||
| 26 | + if (_info.size() > 1) { | ||
| 27 | + if (_is_finished == false) { | ||
| 28 | + printf("add file:%s ,but the last file, %s, is not finished?", info.name.c_str(), _info[_info.size() - 2].name.c_str()); | ||
| 29 | + } | ||
| 30 | + else { | ||
| 31 | + printf("add file:%s ,after the last file, %s", info.name.c_str(), _info[_info.size() - 2].name.c_str()); | ||
| 32 | + } | ||
| 33 | + } | ||
| 34 | + | ||
| 26 | int ret; | 35 | int ret; |
| 27 | 36 | ||
| 28 | do{ | 37 | do{ |
| @@ -731,11 +731,15 @@ int get_output_file_name(const char * filename, const char * prefix,char * outpu | @@ -731,11 +731,15 @@ int get_output_file_name(const char * filename, const char * prefix,char * outpu | ||
| 731 | } | 731 | } |
| 732 | 732 | ||
| 733 | 733 | ||
| 734 | -void save_out_info(float start_time, char * outputfile) | 734 | +void save_out_info(double duration,const char * mediafile) |
| 735 | { | 735 | { |
| 736 | + if (!fp_out_info) { | ||
| 737 | + fp_out_info = fopen(out_info_file, "wt"); | ||
| 738 | + } | ||
| 736 | if (fp_out_info) { | 739 | if (fp_out_info) { |
| 737 | - float duration = get_file_duration(outputfile, false); | ||
| 738 | - fprintf(fp_out_info, "%.3f %.3f %s\n", start_time, duration, outputfile); | 740 | + fprintf(fp_out_info, "%.3f %.3lf %s\n", 0.0f, duration, mediafile); |
| 741 | + fclose(fp_out_info); | ||
| 742 | + fp_out_info = NULL; | ||
| 739 | } | 743 | } |
| 740 | } | 744 | } |
| 741 | 745 | ||
| @@ -955,8 +959,12 @@ int load_record_info(char * record_info) | @@ -955,8 +959,12 @@ int load_record_info(char * record_info) | ||
| 955 | 959 | ||
| 956 | #define MIN_TIME_INTERVAL 25 | 960 | #define MIN_TIME_INTERVAL 25 |
| 957 | 961 | ||
| 958 | -int process_av_files() | 962 | +int process_av_files(char * record_info) |
| 959 | { | 963 | { |
| 964 | + load_record_info(record_info); | ||
| 965 | + | ||
| 966 | + get_outinfo_file_name(record_info); | ||
| 967 | + | ||
| 960 | av_register_all(); | 968 | av_register_all(); |
| 961 | avfilter_register_all(); | 969 | avfilter_register_all(); |
| 962 | 970 | ||
| @@ -964,18 +972,19 @@ int process_av_files() | @@ -964,18 +972,19 @@ int process_av_files() | ||
| 964 | videoTranscoder.set_max_audio(max_audio); | 972 | videoTranscoder.set_max_audio(max_audio); |
| 965 | 973 | ||
| 966 | int64_t cur_time = 0; | 974 | int64_t cur_time = 0; |
| 967 | - bool has_file = sorted_media.size(); | 975 | + bool has_file = sorted_media.size()!=0; |
| 976 | + std::string out_media_file; | ||
| 968 | if (has_file) { | 977 | if (has_file) { |
| 969 | media_info info = sorted_media.front(); | 978 | media_info info = sorted_media.front(); |
| 970 | - std::string m = get_outmedia_file_name(info.name.c_str()); | ||
| 971 | - printf("open output file:%s\n", m.c_str()); | ||
| 972 | - int ret = videoTranscoder.open_output_file(m.c_str()); | 979 | + out_media_file = get_outmedia_file_name(info.name.c_str()); |
| 980 | + printf("open output file:%s\n", out_media_file.c_str()); | ||
| 981 | + int ret = videoTranscoder.open_output_file(out_media_file.c_str()); | ||
| 973 | if (ret) { | 982 | if (ret) { |
| 974 | - printf("open output file:%s fail!\n", m.c_str()); | 983 | + printf("open output file:%s fail!\n", out_media_file.c_str()); |
| 975 | return ret; | 984 | return ret; |
| 976 | } | 985 | } |
| 977 | else { | 986 | else { |
| 978 | - printf("open output file:%s success!\n", m.c_str()); | 987 | + printf("open output file:%s success!\n", out_media_file.c_str()); |
| 979 | } | 988 | } |
| 980 | } | 989 | } |
| 981 | 990 | ||
| @@ -991,7 +1000,7 @@ int process_av_files() | @@ -991,7 +1000,7 @@ int process_av_files() | ||
| 991 | else { | 1000 | else { |
| 992 | break; | 1001 | break; |
| 993 | } | 1002 | } |
| 994 | - has_file = sorted_media.size(); | 1003 | + has_file = sorted_media.size()!=0; |
| 995 | } | 1004 | } |
| 996 | 1005 | ||
| 997 | cur_time = videoTranscoder.transcode(); | 1006 | cur_time = videoTranscoder.transcode(); |
| @@ -1003,6 +1012,8 @@ int process_av_files() | @@ -1003,6 +1012,8 @@ int process_av_files() | ||
| 1003 | 1012 | ||
| 1004 | videoTranscoder.close(); | 1013 | videoTranscoder.close(); |
| 1005 | 1014 | ||
| 1015 | + save_out_info(((double)cur_time)/1000.0, out_media_file.c_str()); | ||
| 1016 | + | ||
| 1006 | return 0; | 1017 | return 0; |
| 1007 | } | 1018 | } |
| 1008 | 1019 | ||
| @@ -1026,7 +1037,5 @@ int main(int argc, char * argv[]) | @@ -1026,7 +1037,5 @@ int main(int argc, char * argv[]) | ||
| 1026 | } | 1037 | } |
| 1027 | } | 1038 | } |
| 1028 | 1039 | ||
| 1029 | - load_record_info(argv[1]); | ||
| 1030 | - | ||
| 1031 | - process_av_files(); | 1040 | + return process_av_files(argv[1]); |
| 1032 | } | 1041 | } |
-
请 注册 或 登录 后发表评论