胡斌

keep last frame in same av segment,need improved

save output info
@@ -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 }