胡斌

support rotate 90 degree,need more test

@@ -24,7 +24,9 @@ _cur_out_v_ts(0), @@ -24,7 +24,9 @@ _cur_out_v_ts(0),
24 _cur_out_a_ts(0), 24 _cur_out_a_ts(0),
25 _max_audio(1), 25 _max_audio(1),
26 _swsCtx(NULL), 26 _swsCtx(NULL),
  27 +_swsCtxPortrait(NULL),
27 _scaledFrame(NULL), 28 _scaledFrame(NULL),
  29 +_scaledPortraitFrame(NULL),
28 _last_videos_got(-1), 30 _last_videos_got(-1),
29 _teacherFrame(NULL), 31 _teacherFrame(NULL),
30 _studentFrame(NULL) 32 _studentFrame(NULL)
@@ -38,17 +40,31 @@ _studentFrame(NULL) @@ -38,17 +40,31 @@ _studentFrame(NULL)
38 _swsCtx = sws_getContext(SRC_W, SRC_H, AV_PIX_FMT_YUV420P, 40 _swsCtx = sws_getContext(SRC_W, SRC_H, AV_PIX_FMT_YUV420P,
39 SCALED_W, SCALED_H, AV_PIX_FMT_YUV420P, SWS_BILINEAR, 41 SCALED_W, SCALED_H, AV_PIX_FMT_YUV420P, SWS_BILINEAR,
40 NULL, NULL, NULL); 42 NULL, NULL, NULL);
  43 + _swsCtxPortrait = sws_getContext(SRC_H, SRC_W, AV_PIX_FMT_YUV420P,
  44 + SCALED_H, SCALED_W, AV_PIX_FMT_YUV420P, SWS_BILINEAR,
  45 + NULL, NULL, NULL);
41 _scaledFrame = av_frame_alloc(); 46 _scaledFrame = av_frame_alloc();
42 _scaledFrame->format = AV_PIX_FMT_YUV420P; 47 _scaledFrame->format = AV_PIX_FMT_YUV420P;
43 _scaledFrame->width = SCALED_W; 48 _scaledFrame->width = SCALED_W;
44 _scaledFrame->height = SCALED_H; 49 _scaledFrame->height = SCALED_H;
45 _scaledFrame->pts = 0; 50 _scaledFrame->pts = 0;
46 51
  52 + _scaledPortraitFrame = av_frame_alloc();
  53 + _scaledPortraitFrame->format = AV_PIX_FMT_YUV420P;
  54 + _scaledPortraitFrame->width = SCALED_H;
  55 + _scaledPortraitFrame->height = SCALED_W;
  56 + _scaledPortraitFrame->pts = 0;
  57 +
47 int ret = av_frame_get_buffer(_scaledFrame, 32); 58 int ret = av_frame_get_buffer(_scaledFrame, 32);
48 if (ret != 0) 59 if (ret != 0)
49 { 60 {
50 printf("Error alloc frame buffer for scaling video frame"); 61 printf("Error alloc frame buffer for scaling video frame");
51 } 62 }
  63 + ret = av_frame_get_buffer(_scaledPortraitFrame, 32);
  64 + if (ret != 0)
  65 + {
  66 + printf("Error alloc frame buffer for scaling portrait video frame");
  67 + }
52 } 68 }
53 RGB2YUV(blank_r, blank_g, blank_b, &_blank_y, &_blank_u, &_blank_v); 69 RGB2YUV(blank_r, blank_g, blank_b, &_blank_y, &_blank_u, &_blank_v);
54 } 70 }
@@ -102,7 +118,6 @@ int64_t CAVTranscoder::transcode() @@ -102,7 +118,6 @@ int64_t CAVTranscoder::transcode()
102 mix_and_output_vframe(decoders_got_frame); 118 mix_and_output_vframe(decoders_got_frame);
103 119
104 _cur_v_time += VFRAME_DURATION_MS; 120 _cur_v_time += VFRAME_DURATION_MS;
105 - //sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);  
106 121
107 while (_cur_a_time < _cur_v_time) 122 while (_cur_a_time < _cur_v_time)
108 { 123 {
@@ -132,17 +147,25 @@ bool CAVTranscoder::all_processed() @@ -132,17 +147,25 @@ bool CAVTranscoder::all_processed()
132 147
133 int CAVTranscoder::close() 148 int CAVTranscoder::close()
134 { 149 {
  150 + flush_encoder(0);
  151 + flush_encoder(1);
  152 + av_write_trailer(_ofmt_ctx);
  153 +
135 if (_swsCtx) { 154 if (_swsCtx) {
136 sws_freeContext(_swsCtx); 155 sws_freeContext(_swsCtx);
137 _swsCtx = NULL; 156 _swsCtx = NULL;
138 } 157 }
  158 +
  159 + if (_swsCtxPortrait){
  160 + sws_freeContext(_swsCtxPortrait);
  161 + _swsCtxPortrait = NULL;
  162 + }
139 if (_scaledFrame) { 163 if (_scaledFrame) {
140 - av_frame_unref(_scaledFrame);  
141 av_frame_free(&_scaledFrame); 164 av_frame_free(&_scaledFrame);
142 } 165 }
143 - flush_encoder(0);  
144 - flush_encoder(1);  
145 - av_write_trailer(_ofmt_ctx); 166 + if (_scaledPortraitFrame) {
  167 + av_frame_free(&_scaledPortraitFrame);
  168 + }
146 169
147 #if USE_H264BSF 170 #if USE_H264BSF
148 av_bitstream_filter_close(h264bsfc); 171 av_bitstream_filter_close(h264bsfc);
@@ -337,10 +360,14 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -337,10 +360,14 @@ int CAVTranscoder::open_output_file(const char *filename)
337 } 360 }
338 361
339 AVFrame *pDstFrame = av_frame_alloc(); 362 AVFrame *pDstFrame = av_frame_alloc();
340 - int nDstSize = avpicture_get_size(AV_PIX_FMT_YUV420P, _nOutputWidth, _nOutputHeight);  
341 - uint8_t *dstbuf = new uint8_t[nDstSize];  
342 - avpicture_fill((AVPicture*)pDstFrame, dstbuf, AV_PIX_FMT_YUV420P, _nOutputWidth, _nOutputHeight);  
343 - 363 + pDstFrame->format = AV_PIX_FMT_YUV420P;
  364 + pDstFrame->width = _nOutputWidth;
  365 + pDstFrame->height = _nOutputHeight;
  366 + int ret = av_frame_get_buffer(pDstFrame, 32);
  367 + if (ret < 0) {
  368 + printf("\n error av_frame_get_buffer: %d", ret);
  369 + return -1;
  370 + }
344 371
345 if (idxTeacher != -1) { 372 if (idxTeacher != -1) {
346 //copy teacher frame to dest frame 373 //copy teacher frame to dest frame
@@ -371,16 +398,33 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -371,16 +398,33 @@ int CAVTranscoder::open_output_file(const char *filename)
371 if (!pFrame) { 398 if (!pFrame) {
372 continue; 399 continue;
373 } 400 }
374 - int h = sws_scale(_swsCtx, pFrame->data, pFrame->linesize, 0, pFrame->height,  
375 - _scaledFrame->data, _scaledFrame->linesize);  
376 - if (h <= 0){  
377 - printf("scale output 0?"); 401 + int h = 0;
  402 + if (pFrame->width == SRC_W && pFrame->height == SRC_H) {
  403 + h = sws_scale(_swsCtx, pFrame->data, pFrame->linesize, 0, pFrame->height,
  404 + _scaledFrame->data, _scaledFrame->linesize);
  405 + if (h <= 0){
  406 + printf("\nscale output result:%d?,ignored", h);
  407 + continue;
  408 + }
  409 + _scaledFrame->pkt_dts = pFrame->pkt_dts;//pass rotation
  410 + 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);
  411 + }
  412 + else if (pFrame->width == SRC_H && pFrame->height == SRC_W) {
  413 + h = sws_scale(_swsCtxPortrait, pFrame->data, pFrame->linesize, 0, pFrame->height,
  414 + _scaledPortraitFrame->data, _scaledPortraitFrame->linesize);
  415 + if (h <= 0){
  416 + printf("\nscale output result:%d?,ignored", h);
  417 + continue;
  418 + }
  419 + _scaledPortraitFrame->pkt_dts = pFrame->pkt_dts;//pass rotation
  420 + fillDestFrame(pDstFrame, _scaledPortraitFrame, SRC_W - (imageIdx % 4 + 1) * (SCALED_H + 5) + 4, SRC_H - SCALED_H + 3 - (SCALED_H + 4)*(imageIdx / 4), 0, (SCALED_W - SCALED_H) / 2, SCALED_H - 3, SCALED_H - 3);
  421 +
  422 + }
  423 + else {
  424 + printf("\nthe frame resolution %dx%d is unexpected! ignored!", pFrame->width, pFrame->height);
  425 + continue;
378 } 426 }
379 427
380 - _scaledFrame->pkt_dts = pFrame->pkt_dts;//pass rotation  
381 -  
382 - //copy each frame to the dest frame  
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);  
384 imageIdx++; 428 imageIdx++;
385 } 429 }
386 } 430 }
@@ -397,7 +441,6 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -397,7 +441,6 @@ int CAVTranscoder::open_output_file(const char *filename)
397 //send to encoder 441 //send to encoder
398 int got_frame = 0; 442 int got_frame = 0;
399 encode_write_frame(pDstFrame, 0, &got_frame); 443 encode_write_frame(pDstFrame, 0, &got_frame);
400 - delete dstbuf;  
401 444
402 return 0; 445 return 0;
403 } 446 }
@@ -407,7 +450,18 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -407,7 +450,18 @@ int CAVTranscoder::open_output_file(const char *filename)
407 if (!pSrcFrame){ 450 if (!pSrcFrame){
408 return 0; 451 return 0;
409 } 452 }
410 - if (pSrcFrame->pkt_dts == 180) { 453 +
  454 + if (pSrcFrame->pkt_dts == 0) {
  455 + for (int i = 0; i < pSrcFrame->height; i++) {
  456 + memcpy(pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x, pSrcFrame->data[0] + i * pSrcFrame->linesize[0], pSrcFrame->linesize[0] > 0 ? pSrcFrame->linesize[0] : -pSrcFrame->linesize[0]);
  457 + }
  458 +
  459 + for (int i = 0; i < pSrcFrame->height / 2; i++){
  460 + memcpy(pDstFrame->data[1] + (y / 2 + i)*pDstFrame->linesize[1] + x / 2, pSrcFrame->data[1] + i * pSrcFrame->linesize[1], pSrcFrame->linesize[1] > 0 ? pSrcFrame->linesize[1] : -pSrcFrame->linesize[1]);
  461 + memcpy(pDstFrame->data[2] + (y / 2 + i)*pDstFrame->linesize[2] + x / 2, pSrcFrame->data[2] + i * pSrcFrame->linesize[2], pSrcFrame->linesize[2] > 0 ? pSrcFrame->linesize[2] : -pSrcFrame->linesize[2]);
  462 + }
  463 + }
  464 + else if (pSrcFrame->pkt_dts == 180) {
411 unsigned char * startSrcY = pSrcFrame->data[0] + pSrcFrame->width + (pSrcFrame->height- 1 ) * pSrcFrame->linesize[0]; 465 unsigned char * startSrcY = pSrcFrame->data[0] + pSrcFrame->width + (pSrcFrame->height- 1 ) * pSrcFrame->linesize[0];
412 for (int i = 0; i < pSrcFrame->height; i++) { 466 for (int i = 0; i < pSrcFrame->height; i++) {
413 unsigned char * psrc = startSrcY - i * pSrcFrame->linesize[0]; 467 unsigned char * psrc = startSrcY - i * pSrcFrame->linesize[0];
@@ -434,22 +488,47 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -434,22 +488,47 @@ int CAVTranscoder::open_output_file(const char *filename)
434 } 488 }
435 } 489 }
436 } 490 }
437 - else { 491 + else if (pSrcFrame->pkt_dts == 90) {
438 for (int i = 0; i < pSrcFrame->height; i++) { 492 for (int i = 0; i < pSrcFrame->height; i++) {
439 - memcpy(pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x, pSrcFrame->data[0] + i * pSrcFrame->linesize[0], pSrcFrame->linesize[0] > 0 ? pSrcFrame->linesize[0] : -pSrcFrame->linesize[0]); 493 + unsigned char * psrc = pSrcFrame->data[0] + i * pSrcFrame->linesize[0];
  494 + unsigned char * psrc_end = psrc + pSrcFrame->width;
  495 + unsigned char * pdst = pDstFrame->data[0] + y * pDstFrame->linesize[0] + pSrcFrame->height -1 - i;
  496 + for (; psrc < psrc_end; psrc++ ,pdst += pDstFrame->linesize[0]) {
  497 + *pdst = *psrc;
  498 + }
440 } 499 }
441 500
442 - for (int i = 0; i < pSrcFrame->height / 2; i++){  
443 - memcpy(pDstFrame->data[1] + (y / 2 + i)*pDstFrame->linesize[1] + x / 2, pSrcFrame->data[1] + i * pSrcFrame->linesize[1], pSrcFrame->linesize[1] > 0 ? pSrcFrame->linesize[1] : -pSrcFrame->linesize[1]);  
444 - memcpy(pDstFrame->data[2] + (y / 2 + i)*pDstFrame->linesize[2] + x / 2, pSrcFrame->data[2] + i * pSrcFrame->linesize[2], pSrcFrame->linesize[2] > 0 ? pSrcFrame->linesize[2] : -pSrcFrame->linesize[2]); 501 + for (int i = 0; i < pSrcFrame->height/2; i++) {
  502 + unsigned char * psrc = pSrcFrame->data[1] + i * pSrcFrame->linesize[1];
  503 + unsigned char * psrc_end = psrc + pSrcFrame->width/2;
  504 + unsigned char * pdst = pDstFrame->data[1] + y /2 * pDstFrame->linesize[1] + pSrcFrame->height/2 -1 - i;
  505 + for (; psrc < psrc_end; psrc++, pdst += pDstFrame->linesize[1]) {
  506 + *pdst = *psrc;
  507 + }
  508 + psrc = pSrcFrame->data[2] + i * pSrcFrame->linesize[2];
  509 + psrc_end = psrc + pSrcFrame->width / 2;
  510 + pdst = pDstFrame->data[2] + y / 2 * pDstFrame->linesize[2] + pSrcFrame->height / 2 - 1 - i;
  511 + for (; psrc < psrc_end; psrc++, pdst += pDstFrame->linesize[2]) {
  512 + *pdst = *psrc;
  513 + }
  514 + }
445 } 515 }
446 - }  
447 return 0; 516 return 0;
448 } 517 }
449 518
450 int CAVTranscoder::fillDestFrame(AVFrame * pDstFrame, AVFrame * pSrcFrame, int x, int y, int srcx, int srcy, int w, int h) 519 int CAVTranscoder::fillDestFrame(AVFrame * pDstFrame, AVFrame * pSrcFrame, int x, int y, int srcx, int srcy, int w, int h)
451 { 520 {
452 - if (pSrcFrame->pkt_dts == 180) { 521 + if (pSrcFrame->pkt_dts == 0) {
  522 + for (int i = 0; i < h; i++) {
  523 + memcpy(pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x, pSrcFrame->data[0] + (i + srcy) * pSrcFrame->linesize[0] + srcx, w);
  524 + }
  525 +
  526 + for (int i = 0; i < h / 2; i++){
  527 + memcpy(pDstFrame->data[1] + (y / 2 + i)*pDstFrame->linesize[1] + x / 2, pSrcFrame->data[1] + (i + srcy / 2) * pSrcFrame->linesize[1], w / 2);
  528 + memcpy(pDstFrame->data[2] + (y / 2 + i)*pDstFrame->linesize[2] + x / 2, pSrcFrame->data[2] + (i + srcy / 2) * pSrcFrame->linesize[2], w / 2);
  529 + }
  530 + }
  531 + else if (pSrcFrame->pkt_dts == 180) {
453 unsigned char * startSrcY = pSrcFrame->data[0] + pSrcFrame->width + (pSrcFrame->height - srcy - 1) * pSrcFrame->linesize[0] - srcx; 532 unsigned char * startSrcY = pSrcFrame->data[0] + pSrcFrame->width + (pSrcFrame->height - srcy - 1) * pSrcFrame->linesize[0] - srcx;
454 for (int i = 0; i < h; i++) { 533 for (int i = 0; i < h; i++) {
455 unsigned char * psrc = startSrcY - i * pSrcFrame->linesize[0]; 534 unsigned char * psrc = startSrcY - i * pSrcFrame->linesize[0];
@@ -476,14 +555,35 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -476,14 +555,35 @@ int CAVTranscoder::open_output_file(const char *filename)
476 } 555 }
477 } 556 }
478 } 557 }
479 - else { 558 + else if (pSrcFrame->pkt_dts == 90) {
  559 + unsigned char * startSrcY = pSrcFrame->data[0] + srcy * pSrcFrame->linesize[0] + srcx;
480 for (int i = 0; i < h; i++) { 560 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); 561 + unsigned char * psrc = startSrcY + i * pSrcFrame->linesize[0];
  562 + unsigned char * psrc_end = psrc + w;
  563 + unsigned char * pdst = pDstFrame->data[0] + y*pDstFrame->linesize[0] + h -1 - i;
  564 + for (; psrc < psrc_end; psrc++, pdst+=pDstFrame->linesize[0]) {
  565 + *pdst = *psrc;
  566 + }
482 } 567 }
483 568
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); 569 + unsigned char * startSrcU = pSrcFrame->data[1] + srcy/2 * pSrcFrame->linesize[1] + srcx/2;
  570 + for (int i = 0; i < h/2; i++) {
  571 + unsigned char * psrc = startSrcU + i* pSrcFrame->linesize[1];
  572 + unsigned char * psrc_end = psrc + w/2;
  573 + unsigned char * pdst = pDstFrame->data[1] + y/2*pDstFrame->linesize[1] + h/2 -1 - i;
  574 + for (; psrc < psrc_end; psrc++, pdst += pDstFrame->linesize[1]) {
  575 + *pdst = *psrc;
  576 + }
  577 + }
  578 +
  579 + unsigned char * startSrcV= pSrcFrame->data[2] + srcy / 2 * pSrcFrame->linesize[2] + srcx / 2;
  580 + for (int i = 0; i < h / 2; i++) {
  581 + unsigned char * psrc = startSrcV + i* pSrcFrame->linesize[2];
  582 + unsigned char * psrc_end = psrc + w / 2;
  583 + unsigned char * pdst = pDstFrame->data[2] + y / 2 * pDstFrame->linesize[2] + h / 2 -1 - i;
  584 + for (; psrc < psrc_end; psrc++, pdst += pDstFrame->linesize[2]) {
  585 + *pdst = *psrc;
  586 + }
487 } 587 }
488 } 588 }
489 return 0; 589 return 0;
@@ -493,9 +593,14 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -493,9 +593,14 @@ int CAVTranscoder::open_output_file(const char *filename)
493 { 593 {
494 //prepare one2one base frame 594 //prepare one2one base frame
495 AVFrame *pDstFrame = av_frame_alloc(); 595 AVFrame *pDstFrame = av_frame_alloc();
496 - int nDstSize = avpicture_get_size(AV_PIX_FMT_YUV420P,_nOutputWidth, _nOutputHeight);  
497 - uint8_t *dstbuf = new uint8_t[nDstSize];  
498 - avpicture_fill((AVPicture*)pDstFrame, dstbuf, AV_PIX_FMT_YUV420P, _nOutputWidth, _nOutputHeight); 596 + pDstFrame->format = AV_PIX_FMT_YUV420P;
  597 + pDstFrame->width = _nOutputWidth;
  598 + pDstFrame->height = _nOutputHeight;
  599 + int ret = av_frame_get_buffer(pDstFrame, 32);
  600 + if (ret < 0) {
  601 + printf("\n error av_frame_get_buffer: %d", ret);
  602 + return -1;
  603 + }
499 604
500 for (unsigned int i = 0; i < decoders_got_frame.size(); i++) { 605 for (unsigned int i = 0; i < decoders_got_frame.size(); i++) {
501 if (decoders_got_frame[i]->_media_role == mr_teacher) { 606 if (decoders_got_frame[i]->_media_role == mr_teacher) {
@@ -525,11 +630,40 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -525,11 +630,40 @@ int CAVTranscoder::open_output_file(const char *filename)
525 if (_teacherFrame) { 630 if (_teacherFrame) {
526 fillDestFrame(pDstFrame, _teacherFrame, 0, 0); 631 fillDestFrame(pDstFrame, _teacherFrame, 0, 0);
527 if (_studentFrame) { 632 if (_studentFrame) {
528 - fillDestFrame(pDstFrame, _studentFrame, 0, 240); 633 + if (_studentFrame->width == SRC_W) {
  634 + if (_studentFrame->pkt_dts != 90){
  635 + fillDestFrame(pDstFrame, _studentFrame, 0, 240);
  636 + }
  637 + else {
  638 + fillDestFrame(pDstFrame, _studentFrame, (SRC_W - SRC_H) / 2, 240, (SRC_W - SRC_H) / 2, 0, SRC_H, SRC_H);
  639 + }
  640 + }
  641 + else if (_studentFrame->pkt_dts != 90){
  642 + fillDestFrame(pDstFrame, _studentFrame, 0, 240);
  643 + }
  644 + else {
  645 + memset(pDstFrame->data[0] + 240 * pDstFrame->linesize[0], _blank_y, _nOutputWidth * _nOutputHeight / 2);
  646 + memset(pDstFrame->data[1] + 120 * pDstFrame->linesize[1], _blank_u, _nOutputWidth * _nOutputHeight / 8);
  647 + memset(pDstFrame->data[2] + 120 * pDstFrame->linesize[2], _blank_v, _nOutputWidth * _nOutputHeight / 8);
  648 + fillDestFrame(pDstFrame, _studentFrame, (SRC_W - SRC_H) / 2, 240, 0, (SRC_W - SRC_H) / 2, SRC_H, SRC_H);
  649 + }
529 } 650 }
530 } 651 }
531 else if (_studentFrame) { 652 else if (_studentFrame) {
532 - fillDestFrame(pDstFrame, _studentFrame, 0, 0); 653 + if (_studentFrame->width == SRC_W) {
  654 + if (_studentFrame->pkt_dts != 90){
  655 + fillDestFrame(pDstFrame, _studentFrame, 0, 0);
  656 + }
  657 + else {
  658 + fillDestFrame(pDstFrame, _studentFrame, (SRC_W - SRC_H) / 2, 0, (SRC_W - SRC_H) / 2, 0, SRC_W, SRC_H);
  659 + }
  660 + }
  661 + else if (_studentFrame->pkt_dts == 90){
  662 + fillDestFrame(pDstFrame, _studentFrame, 0, 0);
  663 + }
  664 + else {
  665 + fillDestFrame(pDstFrame, _studentFrame, (SRC_W - SRC_H) / 2, 0, 0, (SRC_W - SRC_H) / 2, SRC_W, SRC_H);
  666 + }
533 } 667 }
534 668
535 if (decoders_got_frame.size() == 2){ 669 if (decoders_got_frame.size() == 2){
@@ -569,7 +703,6 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -569,7 +703,6 @@ int CAVTranscoder::open_output_file(const char *filename)
569 //send to encoder 703 //send to encoder
570 int got_frame = 0; 704 int got_frame = 0;
571 encode_write_frame(pDstFrame, 0, &got_frame); 705 encode_write_frame(pDstFrame, 0, &got_frame);
572 - delete dstbuf;  
573 706
574 return 0; 707 return 0;
575 } 708 }
@@ -42,7 +42,9 @@ private: @@ -42,7 +42,9 @@ private:
42 void * _a_frame_pool; 42 void * _a_frame_pool;
43 int _max_audio; 43 int _max_audio;
44 struct SwsContext * _swsCtx; 44 struct SwsContext * _swsCtx;
  45 + struct SwsContext * _swsCtxPortrait;
45 AVFrame * _scaledFrame; 46 AVFrame * _scaledFrame;
  47 + AVFrame * _scaledPortraitFrame;
46 int _last_videos_got; 48 int _last_videos_got;
47 AVFrame * _teacherFrame; 49 AVFrame * _teacherFrame;
48 AVFrame * _studentFrame; // for one2one,keep the last frame 50 AVFrame * _studentFrame; // for one2one,keep the last frame
@@ -312,12 +312,9 @@ int CVideoDecoder::filter_encode_write_frame(AVFrame *frame, unsigned int stream @@ -312,12 +312,9 @@ int CVideoDecoder::filter_encode_write_frame(AVFrame *frame, unsigned int stream
312 } 312 }
313 313
314 filt_frame->pict_type = AV_PICTURE_TYPE_NONE; 314 filt_frame->pict_type = AV_PICTURE_TYPE_NONE;
315 - if (_rotate == 180) {  
316 - filt_frame->pkt_dts = 180;//use this to indicate rotate 180  
317 - }  
318 - else {  
319 - filt_frame->pkt_dts = 0;  
320 - } 315 +
  316 + filt_frame->pkt_dts = _rotate;//pass rotate for mixing
  317 +
321 _decoded_frames.push_back(filt_frame); 318 _decoded_frames.push_back(filt_frame);
322 } 319 }
323 320
@@ -1062,7 +1062,7 @@ int process_av_files(char * record_info, int piptype) @@ -1062,7 +1062,7 @@ int process_av_files(char * record_info, int piptype)
1062 encode_loop_count++; 1062 encode_loop_count++;
1063 if (encode_loop_count == 1200) { 1063 if (encode_loop_count == 1200) {
1064 encode_loop_count = 0; 1064 encode_loop_count = 0;
1065 - printf("\n encoded : %d seconds\n", cur_time / 1000); 1065 + printf("\n encoded : %d s\n", cur_time / 1000);
1066 } 1066 }
1067 } 1067 }
1068 1068
@@ -1071,7 +1071,7 @@ int process_av_files(char * record_info, int piptype) @@ -1071,7 +1071,7 @@ int process_av_files(char * record_info, int piptype)
1071 encode_loop_count++; 1071 encode_loop_count++;
1072 if (encode_loop_count == 1200) { 1072 if (encode_loop_count == 1200) {
1073 encode_loop_count = 0; 1073 encode_loop_count = 0;
1074 - printf("\n encoded : %d seconds\n", cur_time / 1000); 1074 + printf("\n encoded : %d s\n", cur_time / 1000);
1075 } 1075 }
1076 } 1076 }
1077 1077
@@ -1081,7 +1081,7 @@ int process_av_files(char * record_info, int piptype) @@ -1081,7 +1081,7 @@ int process_av_files(char * record_info, int piptype)
1081 1081
1082 time(&end); 1082 time(&end);
1083 1083
1084 - printf("\nfinished,used %"PRIu64" second,encoded %.0lf second, the speed ratio is %.3lfX\n", end - start, (double)cur_time / 1000, cur_time / 1000.0 / (end - start)); 1084 + printf("\nfinished,used %"PRIu64" s, encoded %.0lf s, the speed ratio is %.3lfX\n", end - start, (double)cur_time / 1000, cur_time / 1000.0 / (end - start));
1085 1085
1086 return 0; 1086 return 0;
1087 } 1087 }
@@ -1096,16 +1096,16 @@ int main(int argc, char * argv[]) @@ -1096,16 +1096,16 @@ int main(int argc, char * argv[])
1096 return -1; 1096 return -1;
1097 } 1097 }
1098 1098
1099 - get_config_path(); 1099 + //get_config_path();
1100 1100
1101 - load_codec_param(); 1101 + //load_codec_param();
1102 1102
1103 int piptype = 0; 1103 int piptype = 0;
1104 for (int i = 2; i < argc; i++){ 1104 for (int i = 2; i < argc; i++){
1105 if (!strcmp(argv[i], "-t")){ 1105 if (!strcmp(argv[i], "-t")){
1106 i++; 1106 i++;
1107 if (i > argc) { 1107 if (i > argc) {
1108 - printf("error,should be 0,1 or 2 after -t"); 1108 + printf("error,should be 0, 1 or 2 after -t");
1109 return -2; 1109 return -2;
1110 } 1110 }
1111 piptype = atoi(argv[i]); 1111 piptype = atoi(argv[i]);
@@ -70,12 +70,14 @@ @@ -70,12 +70,14 @@
70 <FunctionLevelLinking>true</FunctionLevelLinking> 70 <FunctionLevelLinking>true</FunctionLevelLinking>
71 <IntrinsicFunctions>true</IntrinsicFunctions> 71 <IntrinsicFunctions>true</IntrinsicFunctions>
72 <PreprocessorDefinitions>ADD_FFMPEG_LIB;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> 72 <PreprocessorDefinitions>ADD_FFMPEG_LIB;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  73 + <AdditionalIncludeDirectories>..\..\liveAssistant\third-lib\ffmpeg\include</AdditionalIncludeDirectories>
73 </ClCompile> 74 </ClCompile>
74 <Link> 75 <Link>
75 <SubSystem>Console</SubSystem> 76 <SubSystem>Console</SubSystem>
76 <GenerateDebugInformation>true</GenerateDebugInformation> 77 <GenerateDebugInformation>true</GenerateDebugInformation>
77 <EnableCOMDATFolding>true</EnableCOMDATFolding> 78 <EnableCOMDATFolding>true</EnableCOMDATFolding>
78 <OptimizeReferences>true</OptimizeReferences> 79 <OptimizeReferences>true</OptimizeReferences>
  80 + <AdditionalLibraryDirectories>..\..\liveAssistant\third-lib\ffmpeg\lib;</AdditionalLibraryDirectories>
79 </Link> 81 </Link>
80 </ItemDefinitionGroup> 82 </ItemDefinitionGroup>
81 <ItemGroup> 83 <ItemGroup>