胡斌

improve one2many, keep still image of teacher, rotate and copy cliped image frame of pip

@@ -46,7 +46,7 @@ int CAVDecoder::add(media_info &info) @@ -46,7 +46,7 @@ int CAVDecoder::add(media_info &info)
46 _end_time_ms = info.end_time_ms; 46 _end_time_ms = info.end_time_ms;
47 } 47 }
48 48
49 - av_log(NULL, AV_LOG_INFO, "CAVDecoder add info:%lf, %"PRIu64", %"PRIu64"\n", _cur_a_ts_ms, _cur_v_ts_ms, _end_time_ms); 49 + 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);
50 50
51 return 0; 51 return 0;
52 } 52 }
@@ -341,20 +341,25 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -341,20 +341,25 @@ int CAVTranscoder::open_output_file(const char *filename)
341 uint8_t *dstbuf = new uint8_t[nDstSize]; 341 uint8_t *dstbuf = new uint8_t[nDstSize];
342 avpicture_fill((AVPicture*)pDstFrame, dstbuf, AV_PIX_FMT_YUV420P, _nOutputWidth, _nOutputHeight); 342 avpicture_fill((AVPicture*)pDstFrame, dstbuf, AV_PIX_FMT_YUV420P, _nOutputWidth, _nOutputHeight);
343 343
344 - bool fill_pure_color = true; 344 +
345 if (idxTeacher != -1) { 345 if (idxTeacher != -1) {
346 //copy teacher frame to dest frame 346 //copy teacher frame to dest frame
347 CAVDecoder * pDecoder = decoders_got_frame[idxTeacher]; 347 CAVDecoder * pDecoder = decoders_got_frame[idxTeacher];
348 AVFrame * pFrame = pDecoder->_cur_v_frame; 348 AVFrame * pFrame = pDecoder->_cur_v_frame;
349 if (pFrame) { 349 if (pFrame) {
350 - fillDestFrame(pDstFrame, pFrame, 0, 0);  
351 - fill_pure_color = false; 350 + av_frame_free(&_teacherFrame);
  351 + _teacherFrame = pFrame;
  352 + pDecoder->_cur_v_frame = NULL;
352 } 353 }
353 } 354 }
354 - if(fill_pure_color){//fill with pure color  
355 - memset(pDstFrame->data[0], _blank_y, _nOutputWidth * _nOutputHeight);  
356 - memset(pDstFrame->data[1], _blank_u, _nOutputWidth *_nOutputHeight / 4);  
357 - memset(pDstFrame->data[2], _blank_v, _nOutputWidth * _nOutputHeight / 4); 355 + if (_teacherFrame) {
  356 + fillDestFrame(pDstFrame, _teacherFrame, 0, 0);
  357 + }
  358 + else
  359 + {//fill with pure color
  360 + memset(pDstFrame->data[0], _blank_y, _nOutputWidth * _nOutputHeight);
  361 + memset(pDstFrame->data[1], _blank_u, _nOutputWidth *_nOutputHeight / 4);
  362 + memset(pDstFrame->data[2], _blank_v, _nOutputWidth * _nOutputHeight / 4);
358 } 363 }
359 364
360 int imageIdx = 0; 365 int imageIdx = 0;
@@ -371,9 +376,11 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -371,9 +376,11 @@ int CAVTranscoder::open_output_file(const char *filename)
371 if (h <= 0){ 376 if (h <= 0){
372 printf("scale output 0?"); 377 printf("scale output 0?");
373 } 378 }
  379 +
  380 + _scaledFrame->pkt_dts = pFrame->pkt_dts;//pass rotation
374 381
375 //copy each frame to the dest frame 382 //copy each frame to the dest frame
376 - fillDestFrame(pDstFrame, _scaledFrame, SRC_W - 3 - (imageIdx % 4) * (SCALED_H + 5), SRC_H - SCALED_H - (SCALED_H + 2)*(imageIdx / 4), (SCALED_W - SCALED_H) / 2, 0, SCALED_H-1, SCALED_H-1); 383 + fillDestFrame(pDstFrame, _scaledFrame, SRC_W - (imageIdx % 4 + 1) * (SCALED_H + 5) + 4, SRC_H - SCALED_H + 3 - (SCALED_H + 4)*(imageIdx / 4), (SCALED_W - SCALED_H) / 2, 0, SCALED_H - 3, SCALED_H - 3);
377 imageIdx++; 384 imageIdx++;
378 } 385 }
379 } 386 }
@@ -401,9 +408,8 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -401,9 +408,8 @@ int CAVTranscoder::open_output_file(const char *filename)
401 return 0; 408 return 0;
402 } 409 }
403 if (pSrcFrame->pkt_dts == 180) { 410 if (pSrcFrame->pkt_dts == 180) {
404 - unsigned char * startSrcY = pSrcFrame->data[0] + (pSrcFrame->height) * pSrcFrame->linesize[0] - 1; 411 + unsigned char * startSrcY = pSrcFrame->data[0] + pSrcFrame->width + (pSrcFrame->height- 1 ) * pSrcFrame->linesize[0];
405 for (int i = 0; i < pSrcFrame->height; i++) { 412 for (int i = 0; i < pSrcFrame->height; i++) {
406 - //memcpy(pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x, startSrcY - i * pSrcFrame->linesize[0], pSrcFrame->linesize[0]);  
407 unsigned char * psrc = startSrcY - i * pSrcFrame->linesize[0]; 413 unsigned char * psrc = startSrcY - i * pSrcFrame->linesize[0];
408 unsigned char * pdst = pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x; 414 unsigned char * pdst = pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x;
409 unsigned char * pdst_end = pdst + pSrcFrame->linesize[0]; 415 unsigned char * pdst_end = pdst + pSrcFrame->linesize[0];
@@ -411,11 +417,9 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -411,11 +417,9 @@ int CAVTranscoder::open_output_file(const char *filename)
411 *pdst = *psrc; 417 *pdst = *psrc;
412 } 418 }
413 } 419 }
414 - unsigned char * startSrcU = pSrcFrame->data[1] + (pSrcFrame->height/2 ) * pSrcFrame->linesize[1] -1;  
415 - unsigned char * startSrcV = pSrcFrame->data[2] + (pSrcFrame->height/2) * pSrcFrame->linesize[2] -1; 420 + unsigned char * startSrcU = pSrcFrame->data[1] + pSrcFrame->width/2 + (pSrcFrame->height/2 -1) * pSrcFrame->linesize[1];
  421 + unsigned char * startSrcV = pSrcFrame->data[2] + pSrcFrame->width/2 + (pSrcFrame->height/2 -1) * pSrcFrame->linesize[2];
416 for (int i = 0; i < pSrcFrame->height / 2; i++){ 422 for (int i = 0; i < pSrcFrame->height / 2; i++){
417 - //memcpy(pDstFrame->data[1] + (y / 2 + i)*pDstFrame->linesize[1] + x / 2, startSrcU - i * pSrcFrame->linesize[1], pSrcFrame->linesize[1]);  
418 - //memcpy(pDstFrame->data[2] + (y / 2 + i)*pDstFrame->linesize[2] + x / 2, startSrcV - i * pSrcFrame->linesize[2], pSrcFrame->linesize[2]);  
419 unsigned char * psrc = startSrcU - i * pSrcFrame->linesize[1]; 423 unsigned char * psrc = startSrcU - i * pSrcFrame->linesize[1];
420 unsigned char * pdst = pDstFrame->data[1] + (y/2 + i)*pDstFrame->linesize[1] + x/2; 424 unsigned char * pdst = pDstFrame->data[1] + (y/2 + i)*pDstFrame->linesize[1] + x/2;
421 unsigned char * pdst_end = pdst + pSrcFrame->linesize[1]; 425 unsigned char * pdst_end = pdst + pSrcFrame->linesize[1];
@@ -445,13 +449,42 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -445,13 +449,42 @@ int CAVTranscoder::open_output_file(const char *filename)
445 449
446 int CAVTranscoder::fillDestFrame(AVFrame * pDstFrame, AVFrame * pSrcFrame, int x, int y, int srcx, int srcy, int w, int h) 450 int CAVTranscoder::fillDestFrame(AVFrame * pDstFrame, AVFrame * pSrcFrame, int x, int y, int srcx, int srcy, int w, int h)
447 { 451 {
448 - for (int i = 0; i < h; i++) {  
449 - memcpy(pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x, pSrcFrame->data[0] + (i+srcy) * pSrcFrame->linesize[0] + srcx, pSrcFrame->linesize[0] > 0 ? w : -w); 452 + if (pSrcFrame->pkt_dts == 180) {
  453 + unsigned char * startSrcY = pSrcFrame->data[0] + pSrcFrame->width + (pSrcFrame->height - srcy - 1) * pSrcFrame->linesize[0] - srcx;
  454 + for (int i = 0; i < h; i++) {
  455 + unsigned char * psrc = startSrcY - i * pSrcFrame->linesize[0];
  456 + unsigned char * pdst = pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x;
  457 + unsigned char * pdst_end = pdst + w;
  458 + for (; pdst < pdst_end; psrc--, pdst++) {
  459 + *pdst = *psrc;
  460 + }
  461 + }
  462 + unsigned char * startSrcU = pSrcFrame->data[1] + pSrcFrame->width / 2 + ((pSrcFrame->height - srcy -1)/ 2) * pSrcFrame->linesize[1] - srcx / 2;
  463 + unsigned char * startSrcV = pSrcFrame->data[2] + pSrcFrame->width / 2 + ((pSrcFrame->height - srcy -1)/ 2) * pSrcFrame->linesize[2] - srcx / 2;
  464 + for (int i = 0; i < h / 2; i++){
  465 + unsigned char * psrc = startSrcU - i * pSrcFrame->linesize[1];
  466 + unsigned char * pdst = pDstFrame->data[1] + (y / 2 + i)*pDstFrame->linesize[1] + x / 2;
  467 + unsigned char * pdst_end = pdst + w/2;
  468 + for (; pdst < pdst_end; psrc--, pdst++) {
  469 + *pdst = *psrc;
  470 + }
  471 + psrc = startSrcV - i * pSrcFrame->linesize[2];
  472 + pdst = pDstFrame->data[2] + (y / 2 + i)*pDstFrame->linesize[2] + x / 2;
  473 + pdst_end = pdst + w/2;
  474 + for (; pdst < pdst_end; psrc--, pdst++) {
  475 + *pdst = *psrc;
  476 + }
  477 + }
450 } 478 }
  479 + else {
  480 + for (int i = 0; i < h; i++) {
  481 + memcpy(pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x, pSrcFrame->data[0] + (i + srcy) * pSrcFrame->linesize[0] + srcx, w);
  482 + }
451 483
452 - for (int i = 0; i < h / 2; i++){  
453 - memcpy(pDstFrame->data[1] + (y / 2 + i)*pDstFrame->linesize[1] + x / 2, pSrcFrame->data[1] + (i + srcy/2) * pSrcFrame->linesize[1], pSrcFrame->linesize[1] > 0 ? w/2 : -w/2);  
454 - memcpy(pDstFrame->data[2] + (y / 2 + i)*pDstFrame->linesize[2] + x / 2, pSrcFrame->data[2] + (i + srcy/2) * pSrcFrame->linesize[2], pSrcFrame->linesize[2] > 0 ? w/2 : -w/2); 484 + for (int i = 0; i < h / 2; i++){
  485 + memcpy(pDstFrame->data[1] + (y / 2 + i)*pDstFrame->linesize[1] + x / 2, pSrcFrame->data[1] + (i + srcy / 2) * pSrcFrame->linesize[1], w / 2);
  486 + memcpy(pDstFrame->data[2] + (y / 2 + i)*pDstFrame->linesize[2] + x / 2, pSrcFrame->data[2] + (i + srcy / 2) * pSrcFrame->linesize[2], w / 2);
  487 + }
455 } 488 }
456 return 0; 489 return 0;
457 } 490 }
@@ -483,7 +516,7 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -483,7 +516,7 @@ int CAVTranscoder::open_output_file(const char *filename)
483 } 516 }
484 } 517 }
485 518
486 - if (!_teacherFrame && !_studentFrame) { 519 + if (!_teacherFrame || !_studentFrame) {
487 memset(pDstFrame->data[0], _blank_y, _nOutputWidth * _nOutputHeight); 520 memset(pDstFrame->data[0], _blank_y, _nOutputWidth * _nOutputHeight);
488 memset(pDstFrame->data[1], _blank_u, _nOutputWidth * _nOutputHeight / 4); 521 memset(pDstFrame->data[1], _blank_u, _nOutputWidth * _nOutputHeight / 4);
489 memset(pDstFrame->data[2], _blank_v, _nOutputWidth * _nOutputHeight / 4); 522 memset(pDstFrame->data[2], _blank_v, _nOutputWidth * _nOutputHeight / 4);
@@ -32,7 +32,8 @@ public: @@ -32,7 +32,8 @@ public:
32 int rotate; 32 int rotate;
33 33
34 float duration; 34 float duration;
35 - int index; 35 + int index;//index in record info file
  36 + int sorted_index;//index according to start time
36 unsigned int uid; 37 unsigned int uid;
37 media_type m_type; 38 media_type m_type;
38 media_role m_role; 39 media_role m_role;
@@ -466,8 +466,8 @@ void check_audio_duration() @@ -466,8 +466,8 @@ void check_audio_duration()
466 466
467 467
468 468
469 -list <media_info> sorted_media;  
470 -deque<media_info> sorted_infos; 469 +list <media_info> sorted_media; //sorted media files only by start
  470 +list <media_info> sorted_media_with_end; //sorted media files with end in sort
471 vector<media_info> media_infos; 471 vector<media_info> media_infos;
472 vector<string > merged_files; 472 vector<string > merged_files;
473 vector<string> tmp_files; 473 vector<string> tmp_files;
@@ -566,6 +566,7 @@ void get_video_last_frame_jpeg(const char * video, const char * destfile) { @@ -566,6 +566,7 @@ void get_video_last_frame_jpeg(const char * video, const char * destfile) {
566 } 566 }
567 } 567 }
568 568
  569 +
569 void add_media_info(media_info m) 570 void add_media_info(media_info m)
570 { 571 {
571 list<media_info>::iterator it = sorted_media.begin(); 572 list<media_info>::iterator it = sorted_media.begin();
@@ -574,9 +575,20 @@ void add_media_info(media_info m) @@ -574,9 +575,20 @@ void add_media_info(media_info m)
574 break; 575 break;
575 } 576 }
576 } 577 }
  578 +
577 sorted_media.insert(it, m); 579 sorted_media.insert(it, m);
578 } 580 }
579 581
  582 +void add_media_info_with_end(media_info m)
  583 +{
  584 + list<media_info>::iterator it = sorted_media_with_end.begin();
  585 + for (; it != sorted_media_with_end.end(); it++){
  586 + if (it->type_time > m.type_time){
  587 + break;
  588 + }
  589 + }
  590 + sorted_media_with_end.insert(it, m);
  591 +}
580 592
581 list<media_info> audio_files; 593 list<media_info> audio_files;
582 594
@@ -619,35 +631,40 @@ void add_media_infos() @@ -619,35 +631,40 @@ void add_media_infos()
619 m.start_time_ms = f.start_time * 1000; 631 m.start_time_ms = f.start_time * 1000;
620 m.end_time_ms = f.end_time * 1000; 632 m.end_time_ms = f.end_time * 1000;
621 add_media_info(m); 633 add_media_info(m);
  634 + }
622 635
  636 + list<media_info>::iterator it = sorted_media.begin();
  637 + int index = 0;
  638 + for (; it != sorted_media.end(); it++,index++){
  639 + it->sorted_index = index;
  640 + }
  641 +
  642 + sorted_media_with_end = sorted_media;
  643 +
  644 + it = sorted_media.begin();
  645 + for (; it != sorted_media.end(); it++){
  646 + media_info m = *it;
623 m.t_type = tt_end; 647 m.t_type = tt_end;
624 m.type_time = m.end_time; 648 m.type_time = m.end_time;
625 - add_media_info(m); 649 + add_media_info_with_end(m);
  650 + if (it->m_type == mt_audio) {
  651 + audio_files.push_back(*it);
  652 + }
626 } 653 }
627 654
628 list<media_info> audio_type_files; 655 list<media_info> audio_type_files;
629 656
630 - list<media_info>::iterator it = sorted_media.begin();  
631 - for (; it != sorted_media.end(); it++){ 657 + it = sorted_media_with_end.begin();
  658 + for (; it != sorted_media_with_end.end(); it++){
632 if (it->m_type == mt_audio) { 659 if (it->m_type == mt_audio) {
633 - if (it->t_type == tt_start) {  
634 - audio_files.push_back(*it);  
635 - }  
636 audio_type_files.push_back(*it); 660 audio_type_files.push_back(*it);
637 } 661 }
638 } 662 }
639 663
640 printf("\nsorted file info:"); 664 printf("\nsorted file info:");
641 - it = sorted_media.begin();  
642 - for (; it != sorted_media.end();){  
643 - printf("\n%.3f %s %s", it->type_time, it->name.c_str(), it->t_type == tt_start ? "start" : "end");  
644 - if (it->t_type == tt_end) {  
645 - it = sorted_media.erase(it);  
646 - }  
647 - else  
648 - {  
649 - it++;  
650 - } 665 + it = sorted_media_with_end.begin();
  666 + for (; it != sorted_media_with_end.end();it++){
  667 + printf("\n%2d %8.3f %s %s", it->sorted_index, it->type_time, it->name.c_str(), it->t_type == tt_start ? "start" : "end");
651 } 668 }
652 printf("\n-------------------------\n"); 669 printf("\n-------------------------\n");
653 670
@@ -733,13 +750,13 @@ int get_output_file_name(const char * filename, const char * prefix,char * outpu @@ -733,13 +750,13 @@ int get_output_file_name(const char * filename, const char * prefix,char * outpu
733 } 750 }
734 751
735 752
736 -void save_out_info(double duration,const char * mediafile) 753 +void save_out_info(const char * out_mediafile, const char * firstfile,double duration)
737 { 754 {
738 if (!fp_out_info) { 755 if (!fp_out_info) {
739 fp_out_info = fopen(out_info_file, "wt"); 756 fp_out_info = fopen(out_info_file, "wt");
740 } 757 }
741 if (fp_out_info) { 758 if (fp_out_info) {
742 - fprintf(fp_out_info, "%.3f %.3lf %s\n", 0.0f, duration, mediafile); 759 + fprintf(fp_out_info, "%s %s %.3lf\n", out_mediafile, firstfile, duration);
743 fclose(fp_out_info); 760 fclose(fp_out_info);
744 fp_out_info = NULL; 761 fp_out_info = NULL;
745 } 762 }
@@ -984,10 +1001,11 @@ int process_av_files(char * record_info) @@ -984,10 +1001,11 @@ int process_av_files(char * record_info)
984 1001
985 int64_t cur_time = 0; 1002 int64_t cur_time = 0;
986 bool has_file = sorted_media.size()!=0; 1003 bool has_file = sorted_media.size()!=0;
987 - std::string out_media_file; 1004 + std::string out_media_file,first_media_file;
988 if (has_file) { 1005 if (has_file) {
989 media_info info = sorted_media.front(); 1006 media_info info = sorted_media.front();
990 - out_media_file = get_outmedia_file_name(info.name.c_str()); 1007 + first_media_file = info.name;
  1008 + out_media_file = get_outmedia_file_name(record_info);
991 printf("open output file:%s\n", out_media_file.c_str()); 1009 printf("open output file:%s\n", out_media_file.c_str());
992 int ret = videoTranscoder.open_output_file(out_media_file.c_str()); 1010 int ret = videoTranscoder.open_output_file(out_media_file.c_str());
993 if (ret) { 1011 if (ret) {
@@ -1023,7 +1041,7 @@ int process_av_files(char * record_info) @@ -1023,7 +1041,7 @@ int process_av_files(char * record_info)
1023 1041
1024 videoTranscoder.close(); 1042 videoTranscoder.close();
1025 1043
1026 - save_out_info(((double)cur_time)/1000.0, out_media_file.c_str()); 1044 + save_out_info( out_media_file.c_str(), first_media_file.c_str(),((double)cur_time)/1000.0);
1027 1045
1028 time(&end); 1046 time(&end);
1029 1047