ffmpeg rtsp推流、解碼 課程教學:
ffmpeg實現H264編、解碼,RTSP推流,RTSP解碼
裏面提供源碼可以直接下載運行!
一、ffmpeg初始化
av_register_all(); //初始化FFMPEG
av_init_packet(&pkt);
二、查找解碼器
AVCodecID codec_id = AV_CODEC_ID_H264;
pCodec = avcodec_find_decoder(codec_id);
if (!pCodec)
{
printf("Codec not found\n");
return ;
}
三、分配解碼器空間
pCodecCtx = avcodec_alloc_context3(pCodec);
if (!pCodecCtx)
{
printf("Could not allocate video codec context\n");
return ;
}
四、設置解碼器屬性
pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P; //解碼器的輸出格式
五、打開解碼器
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
{
qDebug()<<"Could not open codec";
return ;
}
六、分配pFrame結構體
pFrame = av_frame_alloc();
if (!pFrame)
{
printf("Could not allocate video frame\n");
return ;
}
七、打開264文件
//打開264文件
fp_in = fopen(filename_in, "rb");
if (!fp_in)
{
printf("Could not open %s\n", filename_in);
return ;
}
int inLen=0;
unsigned char* inBuf=NULL;
unsigned char* outBuf=NULL;
inBuf = (unsigned char*)calloc ( 500000, sizeof(char));
outBuf = (unsigned char*)calloc ( 1000000, sizeof(char));
八、解碼主循環
8.1 找到幀頭
inLen = getNextNal(fp_in, inBuf);
8.2 解碼
int ret= avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, &pkt);
if (ret < 0)
{
printf("avcodec_decode_video2 failed\n");
//return ; //注意不要return 有可能264有一些不是關鍵幀 需要跳過
}
8.3 YUV422--->RGB
//================================ 設置數據轉換參數 ================================//
struct SwsContext *img_convert_ctx;
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL);
//轉換一幀圖像
sws_scale(img_convert_ctx,pFrame->data, pFrame->linesize, 0, pCodecCtx->height, //源
pFrameRGB->data, pFrameRGB->linesize); //目的
8.4 觸發信號,更新繪圖QImage
QImage tmpimage((uchar *)out_buffer,pCodecCtx->width,pCodecCtx->height,QImage::Format_RGB32);
QImage image = tmpimage.copy();
emit sig_GetOneFrame(image); //發送信號
ffmpeg rtsp推流、解碼 課程教學:
ffmpeg實現H264編、解碼,RTSP推流,RTSP解碼
裏面提供源碼可以直接下載運行!
公衆號名稱:玩轉電子世界