胡斌

1.keep still image in one2one mode

2.flip image when retote 180
3.save record info as m_*
4.use stream time base when decode,don't use decode codec time base,because it is varied in some mp4 file
@@ -8,8 +8,8 @@ extern "C" { @@ -8,8 +8,8 @@ extern "C" {
8 #pragma comment(lib,"swscale.lib") 8 #pragma comment(lib,"swscale.lib")
9 #endif 9 #endif
10 10
11 -#define SCALED_W 80  
12 -#define SCALED_H 60 11 +#define SCALED_W 100
  12 +#define SCALED_H 75
13 #define SRC_W 320 13 #define SRC_W 320
14 #define SRC_H 240 14 #define SRC_H 240
15 uint8_t blank_r = 0x16; 15 uint8_t blank_r = 0x16;
@@ -25,7 +25,9 @@ _cur_out_a_ts(0), @@ -25,7 +25,9 @@ _cur_out_a_ts(0),
25 _max_audio(1), 25 _max_audio(1),
26 _swsCtx(NULL), 26 _swsCtx(NULL),
27 _scaledFrame(NULL), 27 _scaledFrame(NULL),
28 -_last_videos_got(-1) 28 +_last_videos_got(-1),
  29 +_teacherFrame(NULL),
  30 +_studentFrame(NULL)
29 { 31 {
30 _one2one = bOne2One; 32 _one2one = bOne2One;
31 if (_one2one) { 33 if (_one2one) {
@@ -54,6 +56,8 @@ _last_videos_got(-1) @@ -54,6 +56,8 @@ _last_videos_got(-1)
54 56
55 CAVTranscoder::~CAVTranscoder() 57 CAVTranscoder::~CAVTranscoder()
56 { 58 {
  59 + av_frame_free(&_teacherFrame);
  60 + av_frame_free(&_studentFrame);
57 } 61 }
58 62
59 int CAVTranscoder::add(media_info & info) 63 int CAVTranscoder::add(media_info & info)
@@ -369,7 +373,7 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -369,7 +373,7 @@ int CAVTranscoder::open_output_file(const char *filename)
369 } 373 }
370 374
371 //copy each frame to the dest frame 375 //copy each frame to the dest frame
372 - 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); 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);
373 imageIdx++; 377 imageIdx++;
374 } 378 }
375 } 379 }
@@ -396,14 +400,45 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -396,14 +400,45 @@ int CAVTranscoder::open_output_file(const char *filename)
396 if (!pSrcFrame){ 400 if (!pSrcFrame){
397 return 0; 401 return 0;
398 } 402 }
399 -  
400 - for (int i = 0; i < pSrcFrame->height; i++) {  
401 - 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]); 403 + if (pSrcFrame->pkt_dts == 180) {
  404 + unsigned char * startSrcY = pSrcFrame->data[0] + (pSrcFrame->height) * pSrcFrame->linesize[0] - 1;
  405 + 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];
  408 + unsigned char * pdst = pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x;
  409 + unsigned char * pdst_end = pdst + pSrcFrame->linesize[0];
  410 + for (; pdst < pdst_end; psrc--, pdst++) {
  411 + *pdst = *psrc;
  412 + }
  413 + }
  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;
  416 + 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];
  420 + unsigned char * pdst = pDstFrame->data[1] + (y/2 + i)*pDstFrame->linesize[1] + x/2;
  421 + unsigned char * pdst_end = pdst + pSrcFrame->linesize[1];
  422 + for (; pdst < pdst_end; psrc--, pdst++) {
  423 + *pdst = *psrc;
  424 + }
  425 + psrc = startSrcV - i * pSrcFrame->linesize[2];
  426 + pdst = pDstFrame->data[2] + (y / 2 + i)*pDstFrame->linesize[2] + x / 2;
  427 + pdst_end = pdst + pSrcFrame->linesize[2];
  428 + for (; pdst < pdst_end; psrc--, pdst++) {
  429 + *pdst = *psrc;
  430 + }
  431 + }
402 } 432 }
  433 + else {
  434 + for (int i = 0; i < pSrcFrame->height; i++) {
  435 + 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]);
  436 + }
403 437
404 - for (int i = 0; i < pSrcFrame->height / 2; i++){  
405 - 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]);  
406 - 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 + for (int i = 0; i < pSrcFrame->height / 2; i++){
  439 + 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]);
  440 + 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]);
  441 + }
407 } 442 }
408 return 0; 443 return 0;
409 } 444 }
@@ -429,18 +464,46 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -429,18 +464,46 @@ int CAVTranscoder::open_output_file(const char *filename)
429 uint8_t *dstbuf = new uint8_t[nDstSize]; 464 uint8_t *dstbuf = new uint8_t[nDstSize];
430 avpicture_fill((AVPicture*)pDstFrame, dstbuf, AV_PIX_FMT_YUV420P, _nOutputWidth, _nOutputHeight); 465 avpicture_fill((AVPicture*)pDstFrame, dstbuf, AV_PIX_FMT_YUV420P, _nOutputWidth, _nOutputHeight);
431 466
432 - memset(pDstFrame->data[0], _blank_y, _nOutputWidth * _nOutputHeight);  
433 - memset(pDstFrame->data[1], _blank_u, _nOutputWidth *_nOutputHeight / 4);  
434 - memset(pDstFrame->data[2], _blank_v, _nOutputWidth * _nOutputHeight / 4); 467 + for (unsigned int i = 0; i < decoders_got_frame.size(); i++) {
  468 + if (decoders_got_frame[i]->_media_role == mr_teacher) {
  469 + AVFrame * pFrame = decoders_got_frame[i]->_cur_v_frame;
  470 + if (pFrame) {
  471 + av_frame_free(&_teacherFrame);
  472 + _teacherFrame = pFrame;
  473 + decoders_got_frame[i]->_cur_v_frame = NULL;
  474 + }
  475 + }
  476 + else {
  477 + AVFrame * pFrame = decoders_got_frame[i]->_cur_v_frame;
  478 + if (pFrame) {
  479 + av_frame_free(&_studentFrame);
  480 + _studentFrame = pFrame;
  481 + decoders_got_frame[i]->_cur_v_frame = NULL;
  482 + }
  483 + }
  484 + }
  485 +
  486 + if (!_teacherFrame && !_studentFrame) {
  487 + memset(pDstFrame->data[0], _blank_y, _nOutputWidth * _nOutputHeight);
  488 + memset(pDstFrame->data[1], _blank_u, _nOutputWidth * _nOutputHeight / 4);
  489 + memset(pDstFrame->data[2], _blank_v, _nOutputWidth * _nOutputHeight / 4);
  490 + }
  491 +
  492 + if (_teacherFrame) {
  493 + fillDestFrame(pDstFrame, _teacherFrame, 0, 0);
  494 + if (_studentFrame) {
  495 + fillDestFrame(pDstFrame, _studentFrame, 0, 240);
  496 + }
  497 + }
  498 + else if (_studentFrame) {
  499 + fillDestFrame(pDstFrame, _studentFrame, 0, 0);
  500 + }
435 501
436 if (decoders_got_frame.size() == 2){ 502 if (decoders_got_frame.size() == 2){
437 if (_last_videos_got != 2) { 503 if (_last_videos_got != 2) {
438 _last_videos_got = 2; 504 _last_videos_got = 2;
439 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()); 505 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());
440 } 506 }
441 - fillDestFrame(pDstFrame, decoders_got_frame[0]->_cur_v_frame, 0, decoders_got_frame[0]->_media_role == mr_teacher ? 0 : 240);  
442 -  
443 - fillDestFrame(pDstFrame, decoders_got_frame[1]->_cur_v_frame, 0, decoders_got_frame[1]->_media_role == mr_teacher ? 0 : 240);  
444 } 507 }
445 else if (decoders_got_frame.size() == 1) 508 else if (decoders_got_frame.size() == 1)
446 { 509 {
@@ -448,15 +511,12 @@ int CAVTranscoder::open_output_file(const char *filename) @@ -448,15 +511,12 @@ int CAVTranscoder::open_output_file(const char *filename)
448 _last_videos_got = 1; 511 _last_videos_got = 1;
449 printf("\n--get 1 video:%"PRIu64", %s\n", _cur_out_v_ts, decoders_got_frame[0]->get_cur_vfile().c_str()); 512 printf("\n--get 1 video:%"PRIu64", %s\n", _cur_out_v_ts, decoders_got_frame[0]->get_cur_vfile().c_str());
450 } 513 }
451 - fillDestFrame(pDstFrame, decoders_got_frame[0]->_cur_v_frame, 0, 0);  
452 - //todo: fill the bottom half image with pure color  
453 } 514 }
454 else { 515 else {
455 if (_last_videos_got != 0) { 516 if (_last_videos_got != 0) {
456 _last_videos_got = 0; 517 _last_videos_got = 0;
457 printf("\n--get 0 video:%"PRIu64"\n", _cur_out_v_ts); 518 printf("\n--get 0 video:%"PRIu64"\n", _cur_out_v_ts);
458 } 519 }
459 - //fill with last image?  
460 } 520 }
461 #if 0 521 #if 0
462 if (_cur_out_v_ts > (26 * 60 + 57) *(1000 /50)) { 522 if (_cur_out_v_ts > (26 * 60 + 57) *(1000 /50)) {
@@ -44,6 +44,8 @@ private: @@ -44,6 +44,8 @@ private:
44 struct SwsContext * _swsCtx; 44 struct SwsContext * _swsCtx;
45 AVFrame * _scaledFrame; 45 AVFrame * _scaledFrame;
46 int _last_videos_got; 46 int _last_videos_got;
  47 + AVFrame * _teacherFrame;
  48 + AVFrame * _studentFrame; // for one2one,keep the last frame
47 49
48 uint8_t _blank_y, _blank_u, _blank_v; 50 uint8_t _blank_y, _blank_u, _blank_v;
49 public: 51 public:
@@ -267,6 +267,7 @@ int CVideoDecoder::open_input_file(const char *filename) @@ -267,6 +267,7 @@ int CVideoDecoder::open_input_file(const char *filename)
267 av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u\n", i); 267 av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u\n", i);
268 return ret; 268 return ret;
269 } 269 }
  270 + codec_ctx->time_base = stream->time_base;
270 } 271 }
271 } 272 }
272 273
@@ -312,12 +313,10 @@ int CVideoDecoder::filter_encode_write_frame(AVFrame *frame, unsigned int stream @@ -312,12 +313,10 @@ int CVideoDecoder::filter_encode_write_frame(AVFrame *frame, unsigned int stream
312 313
313 filt_frame->pict_type = AV_PICTURE_TYPE_NONE; 314 filt_frame->pict_type = AV_PICTURE_TYPE_NONE;
314 if (_rotate == 180) { 315 if (_rotate == 180) {
315 - filt_frame->data[0] += filt_frame->linesize[0] * (filt_frame->height - 1);  
316 - filt_frame->linesize[0] = -filt_frame->linesize[0];  
317 - filt_frame->data[1] += filt_frame->linesize[1] * (filt_frame->height / 2 - 1);  
318 - filt_frame->linesize[1] = -filt_frame->linesize[1];  
319 - filt_frame->data[2] += filt_frame->linesize[2] * (filt_frame->height / 2 - 1);  
320 - filt_frame->linesize[2] = -filt_frame->linesize[2]; 316 + filt_frame->pkt_dts = 180;//use this to indicate rotate 180
  317 + }
  318 + else {
  319 + filt_frame->pkt_dts = 0;
321 } 320 }
322 _decoded_frames.push_back(filt_frame); 321 _decoded_frames.push_back(filt_frame);
323 } 322 }
@@ -372,9 +371,9 @@ int CVideoDecoder::get_one_frame(AVFrame ** pFrame, int64_t & ts) @@ -372,9 +371,9 @@ int CVideoDecoder::get_one_frame(AVFrame ** pFrame, int64_t & ts)
372 break; 371 break;
373 } 372 }
374 373
375 - av_packet_rescale_ts(&packet, 374 + /* av_packet_rescale_ts(&packet,
376 ifmt_ctx->streams[stream_index]->time_base, 375 ifmt_ctx->streams[stream_index]->time_base,
377 - ifmt_ctx->streams[stream_index]->codec->time_base); 376 + ifmt_ctx->streams[stream_index]->codec->time_base);*/
378 dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 : 377 dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 :
379 avcodec_decode_audio4; 378 avcodec_decode_audio4;
380 ret = dec_func(ifmt_ctx->streams[stream_index]->codec, frame, 379 ret = dec_func(ifmt_ctx->streams[stream_index]->codec, frame,
@@ -652,20 +652,22 @@ void add_media_infos() @@ -652,20 +652,22 @@ void add_media_infos()
652 printf("\n-------------------------\n"); 652 printf("\n-------------------------\n");
653 653
654 it = audio_type_files.begin(); 654 it = audio_type_files.begin();
655 - media_info last = *it;  
656 -  
657 - for (it++; it != audio_type_files.end(); it++) {  
658 - if (it->t_type == tt_end) {  
659 - if (last.t_type == tt_start) {  
660 - float mid = (it->type_time + last.type_time) / 2;  
661 - int files_with_mid = count_audio_files(mid);  
662 - if (files_with_mid > max_audio) {  
663 - max_audio = files_with_mid; 655 + if (it != audio_type_files.end()) {
  656 + media_info last = *it;
  657 +
  658 + for (it++; it != audio_type_files.end(); it++) {
  659 + if (it->t_type == tt_end) {
  660 + if (last.t_type == tt_start) {
  661 + float mid = (it->type_time + last.type_time) / 2;
  662 + int files_with_mid = count_audio_files(mid);
  663 + if (files_with_mid > max_audio) {
  664 + max_audio = files_with_mid;
  665 + }
664 } 666 }
665 } 667 }
666 - }  
667 - else {  
668 - last = *it; 668 + else {
  669 + last = *it;
  670 + }
669 } 671 }
670 } 672 }
671 } 673 }
@@ -890,23 +892,30 @@ void load_codec_param() @@ -890,23 +892,30 @@ void load_codec_param()
890 892
891 void get_outinfo_file_name(char * input) 893 void get_outinfo_file_name(char * input)
892 { 894 {
  895 +#if 0
893 strcpy(out_info_file, input); 896 strcpy(out_info_file, input);
894 char * p = strstr(out_info_file, "."); 897 char * p = strstr(out_info_file, ".");
895 if (p) { 898 if (p) {
896 *p = 0; 899 *p = 0;
897 } 900 }
898 strcat(out_info_file, "_out.txt"); 901 strcat(out_info_file, "_out.txt");
  902 +#else
  903 + strcpy(out_info_file, "m_");
  904 + strcat(out_info_file, input);
  905 +#endif
899 } 906 }
900 907
901 string get_outmedia_file_name(const char * input) 908 string get_outmedia_file_name(const char * input)
902 { 909 {
903 char out_media_file[1024]; 910 char out_media_file[1024];
904 - strcpy(out_media_file, input); 911 + strcpy(out_media_file, "m_");
  912 +
  913 + strcat(out_media_file, input);
905 char * p = strstr(out_media_file, "."); 914 char * p = strstr(out_media_file, ".");
906 if (p) { 915 if (p) {
907 *p = 0; 916 *p = 0;
908 } 917 }
909 - strcat(out_media_file, "_out.mp4"); 918 + strcat(out_media_file, ".mp4");
910 return out_media_file; 919 return out_media_file;
911 } 920 }
912 921