胡斌

support the video size of student being 240x240

@@ -23,10 +23,12 @@ _nOutputWidth(320), @@ -23,10 +23,12 @@ _nOutputWidth(320),
23 _cur_out_v_ts(0), 23 _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),  
27 -_swsCtxPortrait(NULL),  
28 -_scaledFrame(NULL),  
29 -_scaledPortraitFrame(NULL), 26 +_swsCtx_320_240(NULL),
  27 +_swsCtx_240_320(NULL),
  28 +_swsCtx_240_240(NULL),
  29 +_scaledFrame_320_240(NULL),
  30 +_scaledFrame_240_320(NULL),
  31 +_scaledFrame_240_240(NULL),
30 _last_videos_got(-1), 32 _last_videos_got(-1),
31 _teacherFrame(NULL), 33 _teacherFrame(NULL),
32 _studentFrame(NULL) 34 _studentFrame(NULL)
@@ -37,34 +39,10 @@ _studentFrame(NULL) @@ -37,34 +39,10 @@ _studentFrame(NULL)
37 } 39 }
38 else { 40 else {
39 _nOutputHeight = 240; 41 _nOutputHeight = 240;
40 - _swsCtx = sws_getContext(SRC_W, SRC_H, AV_PIX_FMT_YUV420P,  
41 - SCALED_W, SCALED_H, AV_PIX_FMT_YUV420P, SWS_BILINEAR,  
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);  
46 - _scaledFrame = av_frame_alloc();  
47 - _scaledFrame->format = AV_PIX_FMT_YUV420P;  
48 - _scaledFrame->width = SCALED_W;  
49 - _scaledFrame->height = SCALED_H;  
50 - _scaledFrame->pts = 0;  
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 -  
58 - int ret = av_frame_get_buffer(_scaledFrame, 32);  
59 - if (ret != 0)  
60 - {  
61 - printf("Error alloc frame buffer for scaling video frame");  
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 - } 42 +
  43 + init_scale_context(&_swsCtx_320_240, &_scaledFrame_320_240, SRC_W, SRC_H, SCALED_W, SCALED_H);
  44 + init_scale_context(&_swsCtx_240_320, &_scaledFrame_240_320, SRC_H, SRC_W, SCALED_H, SCALED_W);
  45 + init_scale_context(&_swsCtx_240_240, &_scaledFrame_240_240, SRC_H, SRC_H, SCALED_H, SCALED_H);
68 } 46 }
69 RGB2YUV(blank_r, blank_g, blank_b, &_blank_y, &_blank_u, &_blank_v); 47 RGB2YUV(blank_r, blank_g, blank_b, &_blank_y, &_blank_u, &_blank_v);
70 } 48 }
@@ -151,21 +129,10 @@ int CAVTranscoder::close() @@ -151,21 +129,10 @@ int CAVTranscoder::close()
151 flush_encoder(1); 129 flush_encoder(1);
152 av_write_trailer(_ofmt_ctx); 130 av_write_trailer(_ofmt_ctx);
153 131
154 - if (_swsCtx) {  
155 - sws_freeContext(_swsCtx);  
156 - _swsCtx = NULL;  
157 - }  
158 -  
159 - if (_swsCtxPortrait){  
160 - sws_freeContext(_swsCtxPortrait);  
161 - _swsCtxPortrait = NULL;  
162 - }  
163 - if (_scaledFrame) {  
164 - av_frame_free(&_scaledFrame);  
165 - }  
166 - if (_scaledPortraitFrame) {  
167 - av_frame_free(&_scaledPortraitFrame);  
168 - } 132 + free_scale_context(&_swsCtx_320_240, &_scaledFrame_320_240);
  133 + free_scale_context(&_swsCtx_240_320, &_scaledFrame_240_320);
  134 + free_scale_context(&_swsCtx_240_240, &_scaledFrame_240_240);
  135 +
169 136
170 #if USE_H264BSF 137 #if USE_H264BSF
171 av_bitstream_filter_close(h264bsfc); 138 av_bitstream_filter_close(h264bsfc);
@@ -401,26 +368,36 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -401,26 +368,36 @@ int CAVTranscoder::open_output_file(const char *filename)
401 } 368 }
402 int h = 0; 369 int h = 0;
403 if (pFrame->width == SRC_W && pFrame->height == SRC_H) { 370 if (pFrame->width == SRC_W && pFrame->height == SRC_H) {
404 - h = sws_scale(_swsCtx, pFrame->data, pFrame->linesize, 0, pFrame->height,  
405 - _scaledFrame->data, _scaledFrame->linesize); 371 + h = sws_scale(_swsCtx_320_240, pFrame->data, pFrame->linesize, 0, pFrame->height,
  372 + _scaledFrame_320_240->data, _scaledFrame_320_240->linesize);
406 if (h <= 0){ 373 if (h <= 0){
407 printf("\nscale output result:%d?,ignored", h); 374 printf("\nscale output result:%d?,ignored", h);
408 continue; 375 continue;
409 } 376 }
410 - _scaledFrame->pkt_dts = pFrame->pkt_dts;//pass rotation  
411 - fillDestFrame(pDstFrame, _scaledFrame, SRC_W - (imageIdx % 4 + 1) * (SCALED_H + 5) + 4, SRC_H - SCALED_H + 3 - (SCALED_H + 1)*(imageIdx / 4), (SCALED_W - SCALED_H) / 2, 0, SCALED_H - 3, SCALED_H - 3); 377 + _scaledFrame_320_240->pkt_dts = pFrame->pkt_dts;//pass rotation
  378 + fillDestFrame(pDstFrame, _scaledFrame_320_240, SRC_W - (imageIdx % 4 + 1) * (SCALED_H + 5) + 4, SRC_H - SCALED_H + 3 - (SCALED_H + 1)*(imageIdx / 4), (SCALED_W - SCALED_H) / 2, 0, SCALED_H - 3, SCALED_H - 3);
412 } 379 }
413 else if (pFrame->width == SRC_H && pFrame->height == SRC_W) { 380 else if (pFrame->width == SRC_H && pFrame->height == SRC_W) {
414 - h = sws_scale(_swsCtxPortrait, pFrame->data, pFrame->linesize, 0, pFrame->height,  
415 - _scaledPortraitFrame->data, _scaledPortraitFrame->linesize); 381 + h = sws_scale(_swsCtx_240_320, pFrame->data, pFrame->linesize, 0, pFrame->height,
  382 + _scaledFrame_240_320->data, _scaledFrame_240_320->linesize);
416 if (h <= 0){ 383 if (h <= 0){
417 printf("\nscale output result:%d?,ignored", h); 384 printf("\nscale output result:%d?,ignored", h);
418 continue; 385 continue;
419 } 386 }
420 - _scaledPortraitFrame->pkt_dts = pFrame->pkt_dts;//pass rotation  
421 - fillDestFrame(pDstFrame, _scaledPortraitFrame, SRC_W - (imageIdx % 4 + 1) * (SCALED_H + 5) + 4, SRC_H - SCALED_H + 3 - (SCALED_H + 1)*(imageIdx / 4), 0, (SCALED_W - SCALED_H) / 2, SCALED_H - 3, SCALED_H - 3); 387 + _scaledFrame_240_320->pkt_dts = pFrame->pkt_dts;//pass rotation
  388 + fillDestFrame(pDstFrame, _scaledFrame_240_320, SRC_W - (imageIdx % 4 + 1) * (SCALED_H + 5) + 4, SRC_H - SCALED_H + 3 - (SCALED_H + 1)*(imageIdx / 4), 0, (SCALED_W - SCALED_H) / 2, SCALED_H - 3, SCALED_H - 3);
422 389
423 } 390 }
  391 + else if (pFrame->width == SRC_H && pFrame->height == SRC_H) {
  392 + h = sws_scale(_swsCtx_240_240, pFrame->data, pFrame->linesize, 0, pFrame->height,
  393 + _scaledFrame_240_240->data, _scaledFrame_240_240->linesize);
  394 + if (h <= 0){
  395 + printf("\nscale output result:%d?,ignored", h);
  396 + continue;
  397 + }
  398 + _scaledFrame_240_240->pkt_dts = pFrame->pkt_dts;//pass rotation
  399 + fillDestFrame(pDstFrame, _scaledFrame_240_240, SRC_W - (imageIdx % 4 + 1) * (SCALED_H + 5) + 4, SRC_H - SCALED_H + 3 - (SCALED_H + 1)*(imageIdx / 4), 0, 0, SCALED_H - 3, SCALED_H - 3);
  400 + }
424 else { 401 else {
425 printf("\nthe frame resolution %dx%d is unexpected! ignored!", pFrame->width, pFrame->height); 402 printf("\nthe frame resolution %dx%d is unexpected! ignored!", pFrame->width, pFrame->height);
426 continue; 403 continue;
@@ -454,12 +431,12 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -454,12 +431,12 @@ int CAVTranscoder::open_output_file(const char *filename)
454 431
455 if (pSrcFrame->pkt_dts == 0) { 432 if (pSrcFrame->pkt_dts == 0) {
456 for (int i = 0; i < pSrcFrame->height; i++) { 433 for (int i = 0; i < pSrcFrame->height; i++) {
457 - 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]); 434 + memcpy(pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x, pSrcFrame->data[0] + i * pSrcFrame->linesize[0], pSrcFrame->width);
458 } 435 }
459 436
460 for (int i = 0; i < pSrcFrame->height / 2; i++){ 437 for (int i = 0; i < pSrcFrame->height / 2; i++){
461 - 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]);  
462 - 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]); 438 + memcpy(pDstFrame->data[1] + (y / 2 + i)*pDstFrame->linesize[1] + x / 2, pSrcFrame->data[1] + i * pSrcFrame->linesize[1], pSrcFrame->width/2);
  439 + memcpy(pDstFrame->data[2] + (y / 2 + i)*pDstFrame->linesize[2] + x / 2, pSrcFrame->data[2] + i * pSrcFrame->linesize[2], pSrcFrame->width/2);
463 } 440 }
464 } 441 }
465 else if (pSrcFrame->pkt_dts == 180) { 442 else if (pSrcFrame->pkt_dts == 180) {
@@ -467,7 +444,7 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -467,7 +444,7 @@ int CAVTranscoder::open_output_file(const char *filename)
467 for (int i = 0; i < pSrcFrame->height; i++) { 444 for (int i = 0; i < pSrcFrame->height; i++) {
468 unsigned char * psrc = startSrcY - i * pSrcFrame->linesize[0]; 445 unsigned char * psrc = startSrcY - i * pSrcFrame->linesize[0];
469 unsigned char * pdst = pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x; 446 unsigned char * pdst = pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x;
470 - unsigned char * pdst_end = pdst + pSrcFrame->linesize[0]; 447 + unsigned char * pdst_end = pdst + pSrcFrame->width;
471 for (; pdst < pdst_end; psrc--, pdst++) { 448 for (; pdst < pdst_end; psrc--, pdst++) {
472 *pdst = *psrc; 449 *pdst = *psrc;
473 } 450 }
@@ -477,13 +454,13 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -477,13 +454,13 @@ int CAVTranscoder::open_output_file(const char *filename)
477 for (int i = 0; i < pSrcFrame->height / 2; i++){ 454 for (int i = 0; i < pSrcFrame->height / 2; i++){
478 unsigned char * psrc = startSrcU - i * pSrcFrame->linesize[1]; 455 unsigned char * psrc = startSrcU - i * pSrcFrame->linesize[1];
479 unsigned char * pdst = pDstFrame->data[1] + (y/2 + i)*pDstFrame->linesize[1] + x/2; 456 unsigned char * pdst = pDstFrame->data[1] + (y/2 + i)*pDstFrame->linesize[1] + x/2;
480 - unsigned char * pdst_end = pdst + pSrcFrame->linesize[1]; 457 + unsigned char * pdst_end = pdst + pSrcFrame->width /2;
481 for (; pdst < pdst_end; psrc--, pdst++) { 458 for (; pdst < pdst_end; psrc--, pdst++) {
482 *pdst = *psrc; 459 *pdst = *psrc;
483 } 460 }
484 psrc = startSrcV - i * pSrcFrame->linesize[2]; 461 psrc = startSrcV - i * pSrcFrame->linesize[2];
485 pdst = pDstFrame->data[2] + (y / 2 + i)*pDstFrame->linesize[2] + x / 2; 462 pdst = pDstFrame->data[2] + (y / 2 + i)*pDstFrame->linesize[2] + x / 2;
486 - pdst_end = pdst + pSrcFrame->linesize[2]; 463 + pdst_end = pdst + pSrcFrame->width /2;
487 for (; pdst < pdst_end; psrc--, pdst++) { 464 for (; pdst < pdst_end; psrc--, pdst++) {
488 *pdst = *psrc; 465 *pdst = *psrc;
489 } 466 }
@@ -493,7 +470,7 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -493,7 +470,7 @@ int CAVTranscoder::open_output_file(const char *filename)
493 for (int i = 0; i < pSrcFrame->height; i++) { 470 for (int i = 0; i < pSrcFrame->height; i++) {
494 unsigned char * psrc = pSrcFrame->data[0] + i * pSrcFrame->linesize[0]; 471 unsigned char * psrc = pSrcFrame->data[0] + i * pSrcFrame->linesize[0];
495 unsigned char * psrc_end = psrc + pSrcFrame->width; 472 unsigned char * psrc_end = psrc + pSrcFrame->width;
496 - unsigned char * pdst = pDstFrame->data[0] + y * pDstFrame->linesize[0] + pSrcFrame->height -1 - i; 473 + unsigned char * pdst = pDstFrame->data[0] + y * pDstFrame->linesize[0] + x + pSrcFrame->height -1 - i;
497 for (; psrc < psrc_end; psrc++ ,pdst += pDstFrame->linesize[0]) { 474 for (; psrc < psrc_end; psrc++ ,pdst += pDstFrame->linesize[0]) {
498 *pdst = *psrc; 475 *pdst = *psrc;
499 } 476 }
@@ -502,13 +479,13 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -502,13 +479,13 @@ int CAVTranscoder::open_output_file(const char *filename)
502 for (int i = 0; i < pSrcFrame->height/2; i++) { 479 for (int i = 0; i < pSrcFrame->height/2; i++) {
503 unsigned char * psrc = pSrcFrame->data[1] + i * pSrcFrame->linesize[1]; 480 unsigned char * psrc = pSrcFrame->data[1] + i * pSrcFrame->linesize[1];
504 unsigned char * psrc_end = psrc + pSrcFrame->width/2; 481 unsigned char * psrc_end = psrc + pSrcFrame->width/2;
505 - unsigned char * pdst = pDstFrame->data[1] + y /2 * pDstFrame->linesize[1] + pSrcFrame->height/2 -1 - i; 482 + unsigned char * pdst = pDstFrame->data[1] + y /2 * pDstFrame->linesize[1] + x/2 + pSrcFrame->height/2 -1 - i;
506 for (; psrc < psrc_end; psrc++, pdst += pDstFrame->linesize[1]) { 483 for (; psrc < psrc_end; psrc++, pdst += pDstFrame->linesize[1]) {
507 *pdst = *psrc; 484 *pdst = *psrc;
508 } 485 }
509 psrc = pSrcFrame->data[2] + i * pSrcFrame->linesize[2]; 486 psrc = pSrcFrame->data[2] + i * pSrcFrame->linesize[2];
510 psrc_end = psrc + pSrcFrame->width / 2; 487 psrc_end = psrc + pSrcFrame->width / 2;
511 - pdst = pDstFrame->data[2] + y / 2 * pDstFrame->linesize[2] + pSrcFrame->height / 2 - 1 - i; 488 + pdst = pDstFrame->data[2] + y / 2 * pDstFrame->linesize[2] + x/2 + pSrcFrame->height / 2 - 1 - i;
512 for (; psrc < psrc_end; psrc++, pdst += pDstFrame->linesize[2]) { 489 for (; psrc < psrc_end; psrc++, pdst += pDstFrame->linesize[2]) {
513 *pdst = *psrc; 490 *pdst = *psrc;
514 } 491 }
@@ -654,7 +631,7 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -654,7 +631,7 @@ int CAVTranscoder::open_output_file(const char *filename)
654 } 631 }
655 } 632 }
656 else if (_studentFrame) { 633 else if (_studentFrame) {
657 - if (_studentFrame->width == SRC_W) { 634 + if (_studentFrame->width == SRC_W && _studentFrame->height == SRC_H) {
658 if (_studentFrame->pkt_dts != 90){ 635 if (_studentFrame->pkt_dts != 90){
659 fillDestFrame(pDstFrame, _studentFrame, 0, 0); 636 fillDestFrame(pDstFrame, _studentFrame, 0, 0);
660 } 637 }
@@ -662,11 +639,19 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -662,11 +639,19 @@ int CAVTranscoder::open_output_file(const char *filename)
662 fillDestFrame(pDstFrame, _studentFrame, (SRC_W - SRC_H) / 2, 0, (SRC_W - SRC_H) / 2, 0, SRC_W, SRC_H); 639 fillDestFrame(pDstFrame, _studentFrame, (SRC_W - SRC_H) / 2, 0, (SRC_W - SRC_H) / 2, 0, SRC_W, SRC_H);
663 } 640 }
664 } 641 }
665 - else if (_studentFrame->pkt_dts == 90){  
666 - fillDestFrame(pDstFrame, _studentFrame, 0, 0); 642 + else if (_studentFrame->width == SRC_H && _studentFrame->height == SRC_W) {
  643 + if (_studentFrame->pkt_dts == 90){
  644 + fillDestFrame(pDstFrame, _studentFrame, 0, 0);
  645 + }
  646 + else {
  647 + fillDestFrame(pDstFrame, _studentFrame, (SRC_W - SRC_H) / 2, 0, 0, (SRC_W - SRC_H) / 2, SRC_W, SRC_H);
  648 + }
  649 + }
  650 + else if (_studentFrame->width == SRC_H && _studentFrame->height == SRC_H) {
  651 + fillDestFrame(pDstFrame, _studentFrame, (SRC_W - SRC_H) / 2, 0);
667 } 652 }
668 else { 653 else {
669 - fillDestFrame(pDstFrame, _studentFrame, (SRC_W - SRC_H) / 2, 0, 0, (SRC_W - SRC_H) / 2, SRC_W, SRC_H); 654 + printf("\nresolution: %dx%d unexpected!", _studentFrame->width, _studentFrame->height);
670 } 655 }
671 } 656 }
672 657
@@ -767,6 +752,39 @@ int CAVTranscoder::flush_encoder(unsigned int stream_index) @@ -767,6 +752,39 @@ int CAVTranscoder::flush_encoder(unsigned int stream_index)
767 return ret; 752 return ret;
768 } 753 }
769 754
  755 +int CAVTranscoder::init_scale_context(SwsContext ** ctx, AVFrame ** frame, int src_w, int src_h, int dest_w, int dest_h)
  756 +{
  757 + *ctx = sws_getContext(src_w, src_h, AV_PIX_FMT_YUV420P,
  758 + dest_w, dest_h, AV_PIX_FMT_YUV420P, SWS_BILINEAR,
  759 + NULL, NULL, NULL);
  760 + *frame = av_frame_alloc();
  761 + (*frame)->format = AV_PIX_FMT_YUV420P;
  762 + (*frame)->width = dest_w;
  763 + (*frame)->height = dest_h;
  764 + (*frame)->pts = 0;
  765 +
  766 +
  767 + int ret = av_frame_get_buffer(*frame, 32);
  768 + if (ret != 0)
  769 + {
  770 + printf("Error alloc frame buffer for scaling video frame");
  771 + }
  772 +
  773 + return ret;
  774 +}
  775 +
  776 +int CAVTranscoder::free_scale_context(SwsContext ** ctx, AVFrame ** frame)
  777 +{
  778 + if (*ctx){
  779 + sws_freeContext(*ctx);
  780 + *ctx = NULL;
  781 + }
  782 + if (*frame) {
  783 + av_frame_free(frame);
  784 + }
  785 + return 0;
  786 +}
  787 +
770 void CAVTranscoder::set_max_audio(int max_audio) 788 void CAVTranscoder::set_max_audio(int max_audio)
771 { 789 {
772 _max_audio = max_audio; 790 _max_audio = max_audio;
@@ -39,12 +39,17 @@ private: @@ -39,12 +39,17 @@ private:
39 int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int *got_frame); 39 int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int *got_frame);
40 int flush_encoder(unsigned int stream_index); 40 int flush_encoder(unsigned int stream_index);
41 41
  42 + int init_scale_context(struct SwsContext ** ctx, AVFrame ** frame, int src_w, int src_h, int dest_w, int dest_h);
  43 + int free_scale_context(struct SwsContext ** ctx, AVFrame ** frame);
  44 +
42 void * _a_frame_pool; 45 void * _a_frame_pool;
43 int _max_audio; 46 int _max_audio;
44 - struct SwsContext * _swsCtx;  
45 - struct SwsContext * _swsCtxPortrait;  
46 - AVFrame * _scaledFrame;  
47 - AVFrame * _scaledPortraitFrame; 47 + struct SwsContext * _swsCtx_320_240;
  48 + struct SwsContext * _swsCtx_240_320;
  49 + struct SwsContext * _swsCtx_240_240;
  50 + AVFrame * _scaledFrame_320_240;
  51 + AVFrame * _scaledFrame_240_320;
  52 + AVFrame * _scaledFrame_240_240;
48 int _last_videos_got; 53 int _last_videos_got;
49 AVFrame * _teacherFrame; 54 AVFrame * _teacherFrame;
50 AVFrame * _studentFrame; // for one2one,keep the last frame 55 AVFrame * _studentFrame; // for one2one,keep the last frame