ffmpeg解碼網路rtp流(包裝的h264)
最近接了一個做ffmpeg解碼的專案,客戶的視訊都是在伺服器上編碼的(H264編碼),編碼後的資料通過rtp封裝傳送到客戶端,客戶端負責解碼顯示。 前期準備: 下載ffmpeg編譯ios版本 檢視ffmpeg的例子程式碼,結果發現都是基於讀檔案的例子,相信很多沒有做過的朋友肯定很著急,呵呵,現在本主給你們發福利了,我把我的程式碼貼上來, 免得後面涉及到這方面的同學走彎路。 標頭檔案如下: // // H264Decoder.h // MICloudPub // // Created by chenjianjun on 14-6-3. // Copyright (c) 2014年 hy. All rights reserved. // #ifndef __MICloudPub___H264Decoder__ #define __MICloudPub___H264Decoder__ #define X264_DECODER_H long class H264Decoder { public: H264Decoder(){} ~H264Decoder(){} public: // H264解碼初期化 X264_DECODER_H X264Decoder_Init(); /* H264資料解碼,解碼後的資料為yuv420格式 dwHandle:初期化時返回的控制代碼 pDataIn:待解碼資料 nInSize:待解碼資料長度 pDataOut:解碼後的資料,儲存空間由呼叫者申請 nOutSize:儲存空間大小 nWidth:解碼後的影象寬度 nHeight:解碼後的影象高度 */ int X264Decoder_Decode(X264_DECODER_H dwHandle, uint8_t *pDataIn, int nInSize, uint8_t *pDataOut, int nOutSize, int *nWidth, int *nHeight); /* H264解碼銷燬 dwHandle:初期化時返回的控制代碼 */ void X264Decoder_UnInit(X264_DECODER_H dwHandle); protected: void pgm_save2(unsigned char *buf, int wrap, int xsize, int ysize, uint8_t *pDataOut) { int i; for(i = 0; i < ysize; i++) { memcpy(pDataOut+i*xsize, buf + /*(ysize-i)*/i * wrap, xsize); } } }; #endif /* defined(__MICloudPub___64Decoder__) */ cpp檔案如下: // // H264Decoder.cpp // MICloudPub // // Created by chenjianjun on 14-6-3. // Copyright (c) 2014年 hy. All rights reserved. // #include "H264Decoder.h" extern "C" { #include "libavformat/avformat.h" #include "libswresample/swresample.h" #include "libavutil/opt.h" #include "libavutil/channel_layout.h" #include "libavutil/parseutils.h" #include "libavutil/samplefmt.h" #include "libavutil/fifo.h" #include "libavutil/intreadwrite.h" #include "libavutil/dict.h" #include "libavutil/mathematics.h" #include "libavutil/pixdesc.h" #include "libavutil/avstring.h" #include "libavutil/imgutils.h" #include "libavfilter/avcodec.h" #include "libavfilter/avfilter.h" #include "libavfilter/buffersrc.h" #include "libavfilter/buffersink.h" } typedef struct { struct AVCodec *codec;// Codec struct AVCodecContext *c;// Codec Context int frame_count; struct AVFrame *picture;// Frame AVPacket avpkt; int iWidth; int iHeight; int comsumedSize; int got_picture; } X264_Decoder_Handle; X264_DECODER_H H264Decoder::X264Decoder_Init() { X264_Decoder_Handle *pHandle = (X264_Decoder_Handle *)malloc(sizeof(X264_Decoder_Handle)); if (pHandle == NULL) { return -1; } avcodec_register_all(); av_init_packet(&(pHandle->avpkt)); pHandle->codec = avcodec_find_decoder(AV_CODEC_ID_H264); if (!pHandle->codec) { return -2; } pHandle->c = avcodec_alloc_context3(pHandle->codec); if (!pHandle->c) { return -3; } pHandle->c->codec_type = AVMEDIA_TYPE_VIDEO; pHandle->c->pix_fmt = PIX_FMT_YUV420P; if (avcodec_open2(pHandle->c, pHandle->codec, NULL) < 0) { return -4; } pHandle->picture = av_frame_alloc(); if (!pHandle->picture) { return -5; } pHandle->frame_count = 0; return (X264_DECODER_H)pHandle; } void H264Decoder::X264Decoder_UnInit(X264_DECODER_H dwHandle) { if (dwHandle <= 0) { return; } X264_Decoder_Handle *pHandle = (X264_Decoder_Handle *)dwHandle; avcodec_close(pHandle->c); av_free(pHandle->c); av_frame_free(&pHandle->picture); free(pHandle); } int H264Decoder::X264Decoder_Decode(X264_DECODER_H dwHandle, uint8_t *pDataIn, int nInSize, uint8_t *pDataOut, int nOutSize, int *nWidth, int *nHeight) { if (dwHandle <= 0) { return -1; } X264_Decoder_Handle *pHandle = (X264_Decoder_Handle *)dwHandle; av_init_packet(&(pHandle->avpkt)); pHandle->avpkt.size = nInSize; pHandle->avpkt.data = pDataIn; while (pHandle->avpkt.size > 0) { pHandle->comsumedSize = avcodec_decode_video2(pHandle->c, pHandle->picture, &pHandle->got_picture, &(pHandle->avpkt)); if (pHandle->comsumedSize < 0) { return -2; } if (pHandle->got_picture) { *nWidth = pHandle->c->width; *nHeight = pHandle->c->height; pgm_save2(pHandle->picture->data[0], pHandle->picture->linesize[0], pHandle->c->width, pHandle->c->height,pDataOut); pgm_save2(pHandle->picture->data[1], pHandle->picture->linesize[1], pHandle->c->width/2, pHandle->c->height/2, pDataOut +pHandle->c->width * pHandle->c->height); pgm_save2(pHandle->picture->data[2], pHandle->picture->linesize[2], pHandle->c->width/2, pHandle->c->height/2, pDataOut +pHandle->c->width * pHandle->c->height*5/4); } if (pHandle->avpkt.data) { pHandle->avpkt.size -= pHandle->comsumedSize; pHandle->avpkt.data += pHandle->comsumedSize; } } return 0; } 主要給大家講講X264Decoder_Decode這個介面的引數說明:
dwHandle:其實就是我們初期化的那個結構體指標 pDataIn:是你接收到的網路資料包,這個資料包必須是完整的幀(如果一幀資料太大的話,伺服器會分包傳送,這個時候就需要客戶端快取重組), 不然會解碼失敗,我做的過程中如果重組後的包不全,h264裡面會報很多莫名的錯誤日誌。 nInSize:接收到的網路資料包 pDataOut:解碼後的資料存放區 nOutSize:解碼後的資料存放區大小 nWidth:解碼後的視訊寬度 nHeight:解碼後的視訊高度 函式裡面有個迴圈解碼的過程,其實你可以寫成解碼一次就行了,這樣寫是考慮解碼的時候是根據naul來解碼的,有可能一幀資料有幾個naul頭。 解碼後的資料通過opengl渲染,效果還不錯。 iphone5 解碼720P的資料,每秒20到25幀的資料,cpu達到85%左右。
相關推薦
ffmpeg解碼網路rtp流(包裝的h264)
最近接了一個做ffmpeg解碼的專案,客戶的視訊都是在伺服器上編碼的(H264編碼),編碼後的資料通過rtp封裝傳送到客戶端,客戶端負責解碼顯示。 前期準備: 下載ffmpeg編譯ios版本 檢視ffmpeg的例子程式碼,結果發現都是基於讀檔案的例子,相信很多沒有做過的
使用 ffmpeg 進行網路推流:拉流->解封裝->解碼->處理原始資料(音訊、視訊)->編碼->編碼->推流
簡要說明: 1、可拉流:rtmp、rtsp、http 2、可推流: #include "stdafx.h" extern "C" { #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #
使用FFMPeg解碼顯示ts流
公司最近專案不是很忙,就將之前弄東西整理了一下,解碼直播流使用FFMPeg, 之前做的一個專案是智慧家居的控制系統,加監控,這個監控有多個攝像頭,每一個都要顯示出來,並將預覽的畫面在不同的位置顯示出來,達到同步的效果,之前使用的VLC解碼顯示的,但是太多預覽源
FFMPEG 實時解碼網路H264碼流,RTP封裝
初學FFMPEG和H264,解碼視訊流時遇到了很多麻煩,記錄一下研究成果。 我使用的FFMPEG 2.5.2版本,使用av_parser_parse2重組影象幀時遇到了一下麻煩! 下面是主要程式碼: RTP頭定義, typedef struct { /**/
FFmpeg解碼H264裸流並轉換成opencv Mat
最近要搞一些視訊推流的事情,要解析H264裸流並且獲取opencv格式的Mat資料給演算法工程師們跑演算法.相關資源一直很難找到,經常都是太舊導致API版本都更新換代了,沒辦法讓新人或者外行[比如我]快速驗證程式碼是否可行.在參考多個部落格,前人的程式碼
03 ffmpeg 解碼SDK調用 H264轉YUV420
03 ffmpeg 解碼sdk調用 h264轉yuv420制作一個H264文件[root@localhost ~]# cd /home/ [root@localhost home]# wget http://sh.yinyuetai.com/uploads/videos/common/0E3E014EBF34
FFmpeg解碼MP4檔案為h264和YUV檔案
#include <iostream> #ifdef __cplusplus extern "C" { #endif #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #in
史上最全的基於ffmpeg+sdl網路攝像頭編解碼播放資料(包含交叉編譯過程,附帶完整原始碼)
原創博文,嚴禁私自轉載,轉載請註明出處!!! 近期,由於工作需要,要在開發板上跑一個攝像頭,攝像頭款式比較老,不支援rtsp格式,所以選擇編譯ffmpeg+sdl實現軟解碼播放攝像頭,特此記錄整個編譯過程(非常之艱辛,發文留念) 在ubuntu上交叉編譯環境的搭建:因為開發板上搭建的程式的執
Live555接收h264使用ffmpeg解碼為YUV42
轉載:http://www.tuicool.com/articles/rmQ732 本文概要: 本文介紹了一種常用成熟的多媒體解碼方案。使用live555作為流媒體資料來源,建立rtsp會話請求h264資料流。後端使用ffmpeg解碼h
使用FFmpeg轉錄網路直播流
愛奇藝萬能播放器的最新版本增加了一個播放網路流的功能。不過,入口藏在播放器區域的右鍵選單裡,不太好找:找來一個直播流URL,比如東森新聞 http://60.199.188.151/HLS/WG_ETTV-N/index.m3u8,試了一下,還不賴呢!有時候,看到精彩的直播內
ffmpeg多執行緒本地mp4 rtmp推流,h264+aac編碼
程式說明:使用了c++11的std執行緒,鎖,訊號量等東西,替換了pthread多執行緒。主要之前用windows下移植的linux發現多執行緒始終有問題,所以決定用原生的試試。不過現在想來,應該問題還是我佇列的設計問題。主要這裡有個坑,就是c語言for迴圈內部
基於FFMPEG SDK流媒體開發1---解碼媒體檔案流資訊
最近專案涉及到流媒體等開發,由於有過開發經驗深知其難度所在,沒辦法只能重新拾起,最新版的SDK被改的一塌糊塗,不過大體的開發思路都是一樣的,看多少書查多少資料都無用,一步一步的編寫程式碼 才是學好的關鍵。。 我會把每一天的學習經過,更新到博文上,希望能給更多想學習的人帶來幫
Live555接收h264使用ffmpeg解碼為YUV420
本文概要: 本文介紹了一種常用成熟的多媒體解碼方案。使用live555作為流媒體資料來源,建立rtsp會話請求h264資料流。後端使用ffmpeg解碼h264流並儲存為yuv420格式。 該方案比較成熟,可行性
ffmpeg解碼h264檔案,opencv顯示
H264.h #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <string.h> #include <winsock2
Android FFMpeg(三)——使用FFMpeg解碼h264、aac
前面部落格記錄了FFMpeg的編譯,編譯後我們可以拿到FFMpeg的動態庫和靜態庫,拿到這些庫檔案後,通常我們需要做個簡單的封裝才能在Android上層愉快的使用。本篇部落格的是從拿到FFMpeg靜態庫到使用FFMpeg解碼視訊的過程,記錄儘可能的詳盡,可能會讓
Android使用FFmpeg 解碼H264並播放(三)
上一節記錄了Android使用FFmpeg解碼H264的過程。這一節記錄在Android上播放的過程。 問題描述 在開發中使用某攝像頭的SDK,只能獲取到一幀幀的 H264 視訊資料,不知道視訊流地址,需要自己解碼出影象並播放。 問題解決 A
Android使用FFmpeg 解碼H264並播放(二)
上一節記錄了Android使用FFmpeg環境搭建過程。這一節記錄視訊解碼過程。 問題描述 在開發中使用某攝像頭的SDK,只能獲取到一幀幀的 H264 視訊資料,不知道視訊流地址,需要自己解碼出影象並播放。 問題解決 編譯FFmpeg 點選
RTSP取流+FFmpeg解碼+OpenGL顯示
該DEMO集合RTSP取流、FFmpeg解碼、OpenGL視訊顯示,自己記錄一下,也跟大家分享一下。 該DEMO參考了以下網站: 1、https://github.com/htwahzs/Rts
在iOS平臺使用ffmpeg解碼h264視訊流
對於視訊檔案和rtsp之類的主流視訊傳輸協議,ffmpeg提供avformat_open_input介面,直接將檔案路徑或URL傳入即可開啟。讀取視訊資料、解碼器初始引數設定等,都可以通過呼叫API來完成。 但是對於h264流,沒有任何封裝格式,也就無法使用libavformat。所以許多工作需要自己手工完
H.264流媒體UDP組播和ffmpeg解碼實驗
簡介:將H.264視訊流從傳送端通過UDP組播到接收端,並通過ffmpeg解碼播放。 分為四步: 1 路由器端區域網下設定虛擬伺服器 2 TCP/UDP通訊測試 3 傳送端與接收端ffmpeg的安裝 4 通過指令對H264流媒體組播和解碼 第一步:區域網下設定虛擬伺服器