當前位置:首頁 » 操作系統 » live555源碼下載

live555源碼下載

發布時間: 2023-09-25 04:19:13

㈠ live555推送1080p花屏

最近一直研究live555推送rtsp流到easydarwin,實現轉發,但是遇到一個問題:live555推送之後的視頻流出現花屏,在網上搜羅一大圈之後找到一個答案,就是live555內部OutPacketBuffer默認大小隻有60000,即是unsigned OutPacketBuffer::maxSize = 60000;當我推送1080p視頻流的時散橡候,用vlc播放,出現部分視頻是花的,主要就是緩沖區太小了,將這個值改大一點即可,目前測試改成288000,視頻不會出現花屏,問題完美解決。

1、大數據幀花屏

live555推送之後的視頻流出現花屏,查看源碼DynamicRTSPServer.cpp文件,源碼如下:

   sms->addSubsession(::createNew(env, fileName, reuseSource));

  } else if (strcmp(extension, ".264") == 0) {

    // Assumed to be a H.264 Video Elementary Stream file:

    NEW_SMS("H.264 Video");

    OutPacketBuffer::maxSize = 100000; // allow for some possibly large H.264 frames

    sms->addSubsession(::createNew(env, fileName, reuseSource));

  } else if (strcmp(extension, ".265") == 0) {

    // Assumed to be a H.265 Video Elementary Stream file:

    NEW_SMS("H.265 Video");

    OutPacketBuffer::maxSize = 100000; // allow for some possibly large H.265 frames

    sms->addSubsession(::createNew(env, fileName, reuseSource));

  } else if (strcmp(extension, ".mp3") == 0) {

    // Assumed to be a MPEG-1 or 2 Audio file:

    NEW_SMS("MPEG-1 or 2 Audio")

查看上面紅色部分對於H264和H265輸出包最大緩沖100000位元組(100K),對於高清視頻緩沖區太小了,必需更改大些。目前更改到沖雹旁800000,對於1080P視頻使用VLC播放時,不會再出現花屏。

2、循環播放文件

在liveMedia庫下的ByteStreamFileSource.cpp文件中的95行,找到

void ByteStreamFileSource::doGetNextFrame() {

  if (feof(fFid) || ferror(fFid) || (fLimitNumBytesToStream && fNumBytesToStream == 0)) {

    handleClosure();

    return;

  }

更改為

void ByteStreamFileSource::doGetNextFrame() {

  if (feof(fFid) || ferror(fFid) || (fLimitNumBytesToStream && fNumBytesToStream == 0)) {

    //handleClosure();

    //肆賀return;

  fseek(fFid, 0, SEEK_SET);

  }

主要思想為,當文件讀完後不讓關閉文件,而是重新讀取文件。經過測試,當VLC關閉RTSP鏈接後,文件會關閉,重新打開其他文件不受影響。

㈡ 讀取實時流時怎樣判斷解壓完一個avpacket

encoding.c
#include<math.h>

#include<libavutil/opt.h>
#include<libavcodec/avcodec.h>
#include<libavutil/imgutils.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<errno.h>
#include<signal.h>

intstop = 0;
constchar *FIFO = "test.264";

/*
* Video encoding example
*/
staticvoid video_encode_example(const char *filename, int codec_id)
{
AVCodec *codec;
AVCodecContext *c= NULL;
int i, ret, x, y, got_output;
FILE *f;
AVFrame *frame;
AVPacket pkt;
uint8_t endcode[] = { 0, 0, 1, 0xb7 };

printf("Encode video file %s\n",filename);

/* find the mpeg1 video encoder */
codec = avcodec_find_encoder(codec_id);
if (!codec)
{
fprintf(stderr, "Codec notfound\n");
exit(1);
}

c = avcodec_alloc_context3(codec);
if (!c)
{
fprintf(stderr, "Could notallocate video codec context\n");
exit(1);
}

/* put sample parameters */
c->bit_rate = 400000;
/* resolution must be a multiple of two */
c->width = 352;
c->height = 288;
/* frames per second */
c->time_base= (AVRational){1,25};
c->gop_size = 10; /* emit one intraframe every ten frames */
c->max_b_frames=1;
c->pix_fmt = AV_PIX_FMT_YUV420P;

if(codec_id == AV_CODEC_ID_H264)
av_opt_set(c->priv_data,"preset", "slow", 0);

/* open it */
if (avcodec_open2(c, codec, NULL) < 0)
{
fprintf(stderr, "Could not opencodec\n");
exit(1);
}

f = fopen(filename, "w");
if (!f)
{
fprintf(stderr, "Could not open%s\n", filename);
exit(1);
}

frame = avcodec_alloc_frame();
if (!frame)
{
fprintf(stderr, "Could notallocate video frame\n");
exit(1);
}
frame->format = c->pix_fmt;
frame->width = c->width;
frame->height = c->height;

/* the image can be allocated by any meansand av_image_alloc() is
* just the most convenient way ifav_malloc() is to be used */
ret = av_image_alloc(frame->data,frame->linesize, c->width, c->height, c->pix_fmt, 32);
if (ret < 0)
{
fprintf(stderr, "Could notallocate raw picture buffer\n");
exit(1);
}

/* encode time second of video */
i = 0;
while (!stop)
{
av_init_packet(&pkt);
pkt.data = NULL; // packet data will be allocated by theencoder
pkt.size = 0;

fflush(stdout);
/* prepare a mmy image */
/* Y */
for(y=0;y<c->height;y++) {
for(x=0;x<c->width;x++) {
frame->data[0][y *frame->linesize[0] + x] = x + y + i * 3;
}
}

/* Cb and Cr */
for(y=0;y<c->height/2;y++) {
for(x=0;x<c->width/2;x++) {
frame->data[1][y *frame->linesize[1] + x] = 128 + y + i * 2;
frame->data[2][y *frame->linesize[2] + x] = 64 + x + i * 5;
}
}

frame->pts = i;

/* encode the image */
ret = avcodec_encode_video2(c,&pkt, frame, &got_output);
if (ret < 0) {
fprintf(stderr, "Errorencoding frame\n");
exit(1);
}

if (got_output) {
printf("Write frame %3d (size=%5d)\n",i, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
i++;
}
相關推薦:RTSP伺服器實例live555源代碼分析
1. RTSP連接的建立過程 RTSPServer類用於構建一個RTSP伺服器,該類同時在其內部定義了一個RTSPClientSession類,用於處理單獨的客戶會話。 首先創建

/* get the delayed frames */
for (got_output = 1; got_output; i++) {
fflush(stdout);

ret = avcodec_encode_video2(c,&pkt, NULL, &got_output);
if (ret < 0) {
fprintf(stderr, "Errorencoding frame\n");
exit(1);
}

if (got_output) {
printf("Write frame %3d(size=%5d)\n", i, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
}

/* add sequence end code to have a realmpeg file */
fwrite(endcode, 1, sizeof(endcode), f);
fclose(f);

avcodec_close(c);
av_free(c);
av_freep(&frame->data[0]);
avcodec_free_frame(&frame);
printf("\n");
}

voidhandle(int sig)
{
if (sig == SIGINT)
stop = 1;
}

intmain(int argc, char **argv)
{
signal(SIGINT, handle);
signal(SIGPIPE, SIG_IGN);

/* register all the codecs */
avcodec_register_all();

if (mkfifo(FIFO, 0644)< 0)
{
if (EEXIST != errno)
{
perror("mkfifo");
exit(1);
}
}

video_encode_example(FIFO,AV_CODEC_ID_H264);

return 0;
}

㈢ live555移植到hi3516做rtsp伺服器

live555庫本身實現了做rtsp伺服器,客戶端可以通過rtsp客戶端訪問伺服器上的文件並播放,支持的文件格式如下:

本次任務實現了把live555移植到嵌入式海思晶元hi3516上做rtsp伺服器,除了支持客戶端播放伺服器上上面格式文件外,另添加了實時播放hi3516攝像頭圖像與音頻的功能。

live555源碼目錄如下:

四個基本的庫分別是:BasicUsageEnvironment, groupsock, liveMedia和UsageEnvironment。
編譯後即生成這4個庫文件:

這里我只簡單說下liveMedia庫的功能,其他三個庫是live555運行的基礎庫,太(mei)簡(yan)單(jiu),就不說了。

liveMedia庫包含了音視頻相關的所有功能,包含音視頻文件的解析,RTP傳輸封裝等,我們可以看到這個目錄下有對h264、AAC等文件解析的支持:

交叉編譯過程:略
這里我主要是修改mediaServer文件夾下的示常式序,添加實時預覽攝像頭圖像與mic聲音功能。
hi3516晶元,視頻編碼格式為h264,音頻編碼格式為AAC。

1.添加音頻AAC支持
添加類 ADTSAudioLiveSource ,繼承自FramedSource

在該類的doGetNextFrame函數里實現獲取hi3516音頻數據做為rtsp伺服器音頻源。
注意點:

1.1 adts默認是帶7位元組或者9位元組的頭,傳給rtsp的時候是要去掉頭的,實際上RTSP通過rtp傳輸AAC幀的時候是不帶adts頭的,而是帶4個位元組的mpeg4-generic頭。

1.2 從FramedSource繼承而來的變數

每次doGetNextFrame幀時,從FIFO里取一個完整的AAC幀,把幀拷貝到fTo buf裡面,然後比較幀大小與fMaxSize來賦值幾個關鍵的變數:

注意,不管幀長是否大於fMaxSize,每次都需要把完整的幀拷貝到fTo指針,live555內部會根據fNumTruncatedBytes等變數自行處理分包。

1.3 doGetNextFrame函數最後不管有沒有取到幀,都需要執行FramedSource::afterGetting

1.4 采樣率,通道數,configstr等的計算

這幾個變數在mediaSubbsession建立RTPsink時要用到,它直接影響了SDP里對於AAC音頻描述欄位的產生

添加類 ,繼承自

createNewStreamSource函數創建上面的ADTSAudioLiveSource做為音頻輸入源,參數estBitrate為預估的碼率,海思AAC編碼碼率設置為24kbps,所以estBitrate設置為24.
createNewRTPSink有必要繼承,因為需要根據音頻源的采樣率、通道數等創建RTPSink.

2.添加h264支持
添加 H264FramedLiveSource ,繼承自FramedSource

unsigned maxFrameSize()函數必須繼承,裡面設置幀最大可能的大小,我設置為100000,如果不繼承就是默認的,會出現畫面馬賽克
doGetNextFrame函數裡面和AAC取幀的處理差不多,我加多了一個步驟,就是第一次取幀的時候會調用介面去產生一個關鍵幀,並且等待這個關鍵幀到來才處理,這樣連接後出圖會比較快。

添加類 ,繼承自

這個類就是實現createNewStreamSource時創建H264FramedLiveSource

3.修改DynamicRTSPServer
修改類DynamicRTSPServer,在lookupServerMediaSession函數里動點手腳,默認在這個函數裡面會根據文件名去尋找伺服器下相應的文件做為直播源,我這里比較如果是我特定的live源名字則直接返回,相應的live源創建rtsp伺服器的時候就添加好

4.初始化rtsp server
初始化rtsp伺服器,添加一個ServerMediaSession,該mediaSession添加一個和一個,然後把該mediaSession添加給rtsp伺服器。

客戶端訪問 rtsp://x.x.x.x/ch0.live 時就可以看到實時的攝像頭圖像與聲音啦!

㈣ 編譯android-vlc支持rtsp,是不是需要添加live555誰有詳細的步驟呢給說下,最好有編譯好的源碼

vlc-android是直接支持rtsp的,可以播放rtsp。http,mms網路流 我編譯好了一份源代碼,你可以下載看看 http://download.csdn.net/detail/wng2010/4971056

㈤ Live555 源代碼分析(二)

Live555對常用的socket操作進行了包裝。

setupDatagramSocket()創建UDP socket。

setupStreamSocket()創建TCP socket。

increaseSendBufferTo()調用setsockopt(),增加發送緩存的大小。

writeSocket()和readSocket()分別發送和接收數據包。

ourIPAddress()得到本地地址。

RTPInterface負責發送、接收數據包。

TCP協議和UDP協議都可以承載數據包。一個RTPInterface實例可以同時支持多路TCP數據和多路UDP數據。對於TCP,一個TCP連接上可以有多個channel,每個channel對應一路數據。

RTPInterface自己處理TCP部分。這其中需要藉助tcpStreamRecord和SocketDescriptor。

RTPInterface將UDP部分委託給Groupsock,一個GroupSock實例處理多個UDP連接。

因為不同channel共用同一個TCP連接,所以SocketDescriptor發送數據包時,會加上一個數據包頭,其中對不同channel加以區分。

TCP連接上的數據格式如下圖所示。

RTPInterface::addStreamSocket()創建tcpStreamRecord實例,並注冊到對應的SocketDescriptor實例中,以便監控socket的可讀數據。

RTPInterface::sendRTPorRTPPacketOverTCP(),向單個TCP連接發送數據包。

_Tables的成員socketTable保存了全局唯一的SocketDescriptor的hash表。

SocketDescriptor管理一個TCP socket,以及承載在它上面的channel。

對於SocketDescriptor,

SocketDescriptor::registerRTPInterface()還同時將SocketDescriptor::tcpReadHandler()設置為socket的監聽函數。

當socket有數據可讀時,SocketDescriptor::tcpReadHandler()被調用。

在tcpReadHandler1()中,

NetInterface和Socket定義了網路介面。

Port保存埠號,它的成員fPortNum是網路位元組序的埠號。

對於NetInterface,

對於Socket,

Socket的構造函數調用setupDatagramSocket()創建socket,綁定本地埠號fPort,地址預設為INADDR_ANY,即由協議層決定。

OutputSocket和GroupSock分別實現了write()和handleRead()。

對於OutputSocket,

對於GroupSock,

成員函數output()遍歷fDests中的組播地址,向它們發送數據包。

成員函數handleRead()負責接收消息。它調用全局函數readSocket(),後者調用recvfrom()接收數據包。接收的數據通過handleRead()返回給調用者。

RTPInterface::sendPacket()發送數據包。

5.7.用RTPInterface接收數據

成員函數startNetworkReading()開始監聽所有的TCP和UDP連接。調用者需要指定有數據可讀時的回調函數。

當RTCPInterface的UDP或TCP socket有數據可讀時,調用者指定的回調函數被調用。這時它應該調用RTCPInterface::handleRead()讀取數據。

RTCPInstance從RTPSink的信息構造RTCP數據包,然後通過RTPInterface發送出去。OutPacketBuffer作為發送緩存使用。

對於OutPacketBuffer,

對於RTCPInstance,

RTCPInstance::sendReport()是發送數據包的例子。它先調用addReport()和addSDES()構造數據包,然後在調用sendBuiltPacket()發送它。sendBuiltPacket使用了RTPInterface::sendPacket()。

RTCPInstance::schele()設置一個超時任務。如果某些預期的事,沒有在指定時間內發生,則觸發指定的回調函數RTCPInstance::onExpire()進行重試。

RTCPInstace::onExpire()調用全局函數OnExpire()。在OnExpire()中,檢查哪些事件沒有如期發生,如發送BYE消息或其他消息沒有成功,則重新嘗試。

RTCPInstance::setByeHandler()設置一個回調函數,收到對應消息時,該回調函數被調用。這個回調函數保存在成員fByeHandlerTask。

在RTCPInstance的構造函數中,調用RTCPInterface::startNetworkReading()。其中將RTCPInstance::incomingReportHandler()設置為數據可讀時的回調函數。

在RTCPInstance::incomingReportHandler()中,

熱點內容
我的世界伺服器房間號2020電腦版 發布:2025-01-24 01:28:05 瀏覽:398
微信提示存儲空間不足 發布:2025-01-24 01:19:53 瀏覽:963
安卓電腦管家如何清除緩存 發布:2025-01-24 00:55:42 瀏覽:148
怎麼上傳歌曲到qq音樂 發布:2025-01-24 00:45:30 瀏覽:65
養貓用什麼配置 發布:2025-01-24 00:37:58 瀏覽:812
pythongps 發布:2025-01-24 00:37:51 瀏覽:813
辦公編程滑鼠 發布:2025-01-24 00:37:07 瀏覽:386
wpa加密類型 發布:2025-01-24 00:35:58 瀏覽:960
如何用批處理實現ftp映射盤符 發布:2025-01-24 00:25:45 瀏覽:954
win7sql版本 發布:2025-01-24 00:22:16 瀏覽:499