123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- /**
- * 叶海辉
- * QQ群121376426
- * http://blog.yundiantech.com/
- */
- #include "screenrecorder.h"
- #include <QDateTime>
- #include <QDebug>
- extern int audio_input_frame_size;
- ScreenRecorder::ScreenRecorder()
- {
- m_isRun = false;
- }
- ScreenRecorder::~ScreenRecorder()
- {
- }
- ErroCode ScreenRecorder::init(QString audioDevName)
- {
- AVCodec *pCodec = NULL;
- AVCodec *aCodec = NULL;
- av_register_all();
- avformat_network_init();
- avdevice_register_all(); //Register Device
- pFormatCtx = avformat_alloc_context();
- AVInputFormat *ifmt = av_find_input_format("dshow");
- QString audioDevOption = QString("audio=%1").arg(audioDevName);
- if(avformat_open_input(&pFormatCtx,audioDevOption.toUtf8(),ifmt,NULL)!=0){
- fprintf(stderr,"Couldn't open input stream audio.(无法打开输入流)\n");
- return AudioOpenFailed;
- }
- if(avformat_open_input(&pFormatCtx,"video=screen-capture-recorder",ifmt,NULL)!=0){
- fprintf(stderr,"Couldn't open input stream video.(无法打开输入流)\n");
- return VideoOpenFailed;
- }
- videoindex=-1;
- for(i=0; i<pFormatCtx->nb_streams; i++)
- if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
- {
- videoindex=i;
- break;
- }
- if(videoindex==-1)
- {
- printf("Didn't find a video stream.(没有找到视频流)\n");
- return VideoOpenFailed;
- }
- pCodecCtx = pFormatCtx->streams[videoindex]->codec;
- pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
- if(pCodec == NULL)
- {
- printf("video Codec not found.\n");
- return VideoDecoderOpenFailed;
- }
- if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
- {
- printf("Could not open video codec.\n");
- return VideoDecoderOpenFailed;
- }
- audioindex = -1;
- aCodecCtx = NULL;
- for(i=0; i<pFormatCtx->nb_streams; i++)
- if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO)
- {
- audioindex=i;
- break;
- }
- if(audioindex==-1)
- {
- printf("Didn't find a video stream.(没有找到视频流)\n");
- return AudioOpenFailed;
- }
- aCodecCtx = pFormatCtx->streams[audioindex]->codec;
- aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
- if(aCodec == NULL)
- {
- printf("audio Codec not found.\n");
- return AudioDecoderOpenFailed;
- }
- if(avcodec_open2(aCodecCtx, aCodec,NULL)<0)
- {
- printf("Could not open video codec.\n");
- return AudioDecoderOpenFailed;
- }
- aFrame=avcodec_alloc_frame();
- pFrame=avcodec_alloc_frame();
- pFrameYUV=avcodec_alloc_frame();
- out_buffer=(uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));
- avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
- setWidth(pCodecCtx->width, pCodecCtx->height);
- return SUCCEED;
- }
- void ScreenRecorder::deInit()
- {
- av_free(out_buffer);
- av_free(aFrame);
- av_free(pFrame);
- av_free(pFrameYUV);
- avcodec_close(pCodecCtx);
- if (aCodecCtx)
- avcodec_close(aCodecCtx);
- ///下面这2个释放这里会奔溃 这里先无视 后面再完善它
- // avformat_close_input(&pFormatCtx);
- // avformat_free_context(pFormatCtx);
- }
- void ScreenRecorder::startRecord()
- {
- m_isRun = true;
- // m_writeFile->startWrite();
- startEncode();
- start();
- }
- void ScreenRecorder::stopRecord()
- {
- m_isRun = false;
- stopEncode();
- }
- void ScreenRecorder::run()
- {
- int ret, got_frame;
- AVPacket *packet=(AVPacket *)av_malloc(sizeof(AVPacket));
- // //Output Information-----------------------------
- // printf("File Information(文件信息)---------------------\n");
- // av_dump_format(pFormatCtx,0,NULL,0);
- // printf("-------------------------------------------------\n");
- struct SwsContext *img_convert_ctx;
- img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
- //------------------------------
- int y_size = pCodecCtx->width * pCodecCtx->height;
- int size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
- qint64 firstTime = QDateTime::currentMSecsSinceEpoch();
- while(m_isRun )
- {
- if (av_read_frame(pFormatCtx, packet)<0)
- {
- msleep(10);
- continue;
- }
- if(packet->stream_index==videoindex)
- {
- qint64 secondTime = QDateTime::currentMSecsSinceEpoch();
- if ((secondTime - firstTime) >= 100)
- {
- firstTime = secondTime;
- ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_frame, packet);
- if(ret < 0)
- {
- printf("video Decode Error.(解码错误)\n");
- return;
- }
- if(got_frame)
- {
- sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
- uint8_t * picture_buf = (uint8_t *)av_malloc(size);
- memcpy(picture_buf,pFrameYUV->data[0],y_size);
- memcpy(picture_buf+y_size,pFrameYUV->data[1],y_size/4);
- memcpy(picture_buf+y_size+y_size/4,pFrameYUV->data[2],y_size/4);
- videoDataQuene_Input(picture_buf,y_size*3/2);
- }
- }
- }
- else if(packet->stream_index == audioindex)
- {
- ret = avcodec_decode_audio4(aCodecCtx, aFrame, &got_frame, packet);
- if(ret < 0)
- {
- fprintf(stderr,"video Audio Error.\n");
- return;
- }
- if (got_frame)
- {
- int size = av_samples_get_buffer_size(NULL,aCodecCtx->channels, aFrame->nb_samples,aCodecCtx->sample_fmt, 1);
- int index = 0;
- int ONEAudioSize = audio_input_frame_size * 4;//4096
- for (int i=0;i<(size/ONEAudioSize);i++)
- {
- int framSize = ONEAudioSize;
- if (i==size/ONEAudioSize)
- {
- framSize = size%ONEAudioSize;
- }
- if (framSize<=0){
- break;
- }
- uint8_t * audio_buf = (uint8_t *)malloc(4096*2);
- memcpy(audio_buf, aFrame->data[0]+index, framSize);
- audioDataQuene_Input((uint8_t*)audio_buf,ONEAudioSize);
- index += framSize;
- }
- }
- }
- av_free_packet(packet);
- }
- qDebug()<<"record stopping...";
- // m_writeFile->stopWrite();
- qDebug()<<"record finished!";
- sws_freeContext(img_convert_ctx);
- deInit();
- }
|