1. 程式人生 > >live555 server mediacodec應用

live555 server mediacodec應用

live555 server + mediacodec

java端建立快取檔案, 開啟camera preview並呼叫mediacodec編碼攝像頭預覽資料,把視訊編碼資料寫入快取檔案,呼叫jni端live555的H264VideoFileServerMediaSubsession建立H.264視訊檔案流服務子會話(簡單驗證實時的視訊流服務功能,檔案寫入、讀出方式實現視訊流服務的方式,效率比較低)

Java端:
StreamerActivity2:

 static {
         ...
         System.loadLibrary("live555");
       System.loadLibrary("streamer"
); } ... public static native void end(); public static native void RtspTempFile(String filename); //1、建立快取檔案 public static native void WriteRtspFrame(byte[] data, int size); //jni端寫編碼資料入快取檔案,測試用 public static native int RtspServer(String filename); //2、呼叫live555的H264VideoFileServerMediaSubsession,實現.264視訊檔案媒體會話子服務
//yv12 轉 yuv420p yvu -> yuv private void swapYV12toI420(byte[] yv12bytes, byte[] i420bytes, int width, int height) { System.arraycopy(yv12bytes, 0, i420bytes, 0,width*height); System.arraycopy(yv12bytes, width*height+width*height/4, i420bytes, width*height,width*height/4
); System.arraycopy(yv12bytes, width*height, i420bytes, width*height+width*height/4,width*height/4); } // MediaCodec(型別為"video/avc") 同步編碼 public void onFrame(byte[] buf, int length) { swapYV12toI420(buf, h264, width, height); ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers(); ByteBuffer[] outputBuffers = mediaCodec.getOutputBuffers(); int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1); if (inputBufferIndex >= 0) { ByteBuffer inputBuffer = inputBuffers[inputBufferIndex]; inputBuffer.clear(); inputBuffer.put(h264, 0, length); mediaCodec.queueInputBuffer(inputBufferIndex, 0, length, 0, 0); } MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo,0); while (outputBufferIndex >= 0) { ByteBuffer outputBuffer = outputBuffers[outputBufferIndex]; byte[] outData = new byte[bufferInfo.size]; outputBuffer.get(outData); if(runOneFlag){ if(outData.length == 21){ System.arraycopy(outData, 0, outData0, 0, 21); //暫存sps pps,編碼器會一次性輸出sps和pps包(sps pps長度因視訊高、寬等引數會有差異, //編碼器輸出的nalu單元自動帶start code) runOneFlag = false; } } runPushFlag = true; if(runPushFlag) { if(runTestFlag) { frame_count2++; if(frame_count2 >= 50){ //快取50幀 runTestFlag = false; new Thread() { @Override public void run() { RtspServer(h264Path); //開啟RTSPServer的 H264VideoFileServerMediaSubsession } }.start(); } } try { outputStream.write(outData, 0, outData.length); //nalu資料,jav端a寫入.264檔案, outputStream = new BufferedOutputStream(new FileOutputStream(**)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //WriteRtspFrame(outData, outData.length); //nalu資料,jni端寫入.264檔案 mediaCodec.releaseOutputBuffer(outputBufferIndex, false); outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0); } }

JNI端:
streamer.cpp:

JNIEXPORT jint JNICALL Java_com_example_mylive55servermediacodec_StreamerActivity2_RtspServer
(JNIEnv *env1, jobject obj, jstring filename)
{
    TaskScheduler* scheduler = BasicTaskScheduler::createNew();
    UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler);

    UserAuthenticationDatabase* authDB = NULL;

    RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554, authDB);
    if (rtspServer == NULL) {
        LOGI("Failed to create RTSP server:%s", env->getResultMsg());
        return -1;
    }
    char const* descriptionString = "Session streamed by \"testOnDemandRTSPServer\"";

    quit = 0;
    ServerMediaSession* sms = NULL;
    // A H.264 video elementary stream:
    {
        char const* streamName = "mstreamer";
        char const* inputFileName = env1->GetStringUTFChars(filename, NULL); 

        LOGI("   inputFileName = %s", inputFileName);
      sms = ServerMediaSession::createNew(*env, streamName, streamName, descriptionString);
        sms->addSubsession(H264VideoFileServerMediaSubsession::createNew(*env, inputFileName, reuseFirstSource0));
        rtspServer->addServerMediaSession(sms);

        announceStream0(rtspServer, sms, streamName, inputFileName);
    }
  /*
    {
        char const* streamName = "ts";
        char const* inputFileName = "/sdcard/H264_720p.ts";
        char const* indexFileName = "test.tsx";
        ServerMediaSession* sms = ServerMediaSession::createNew(*env,
                streamName, streamName, descriptionString);
        sms->addSubsession(
                MPEG2TransportFileServerMediaSubsession::createNew(*env,
                        inputFileName, indexFileName, reuseFirstSource0));
        rtspServer->addServerMediaSession(sms);

        announceStream0(rtspServer, sms, streamName, inputFileName);
    }
  */
    if (rtspServer->setUpTunnelingOverHTTP(80)
            || rtspServer->setUpTunnelingOverHTTP(8000)
            || rtspServer->setUpTunnelingOverHTTP(8080)) {
        LOGI("we use port-->%d", rtspServer->httpServerPortNum());
    } else {
        LOGI("RTSP-over-HTTP tunneling is not available.");
    }

    env->taskScheduler().doEventLoop(&quit);

    rtspServer->removeServerMediaSession(sms);
    Medium::close(rtspServer);

    env->reclaim();
    env = NULL;
  delete scheduler;
    scheduler = NULL;

    LOGI("......End......\n");

    return 0;
}

JNIEXPORT void JNICALL Java_com_example_mylive55servermediacodec_StreamerActivity2_end(JNIEnv *env, jobject obj) {
     LOGI("Ending streaming...\n");
     quit = 1;
     // Medium::close(rtspServer);
}

JNIEXPORT void JNICALL Java_com_example_mylive55servermediacodec_StreamerActivity2_RtspTempFile
(JNIEnv *env, jobject obj, jstring filename)
{
    char const*inputFilename0 = env->GetStringUTFChars(filename, NULL);
    inputFilename = inputFilename0;

    file = fopen(inputFilename0, "wb+");
    if (!file) {
        LOGE("couldn't open %s", inputFilename0);
        exit(1);
    }

    LOGE("  RtspTempFile open %s  ", inputFilename0);
}

//新增視訊幀的方法
JNIEXPORT void JNICALL Java_com_example_mylive55servermediacodec_StreamerActivity2_WriteRtspFrame(
        JNIEnv *env, jclass clz, jbyteArray data, jint size)
{
    unsigned char *buf = (unsigned char *)env->GetByteArrayElements(data, JNI_FALSE);
    //length
    pthread_mutex_lock(&mutex);
  int ret = fwrite(buf, 1, size, file);
  if(ret != 0){
       LOGI(" IDR = %d, %d", ret, size);
  }
  pthread_mutex_unlock(&mutex);
    env->ReleaseByteArrayElements(data, (jbyte *)buf, 0);
}

這裡寫圖片描述

這裡寫圖片描述

相關推薦

live555 server mediacodec應用

live555 server + mediacodec java端建立快取檔案, 開啟camera preview並呼叫mediacodec編碼攝像頭預覽資料,把視訊編碼資料寫入快取檔案,呼叫jni端live555的H264VideoFileServerM

SQL SERVER DATETIME應用

print flow and .com bold class lin eight spa PRINT ‘上周的第一天:‘+CONVERT(NVARCHAR(20),DATEADD(WEEK, DATEDIFF(WEEK, 0, GETDATE())-1, 0),120);

使用loki+ mtail + grafana + prometheus server分析應用問題

loki 是一個方便的類似prometheus 的log 系統,mtail 是一個方便的日誌提取工具, 可以暴露為http 服務——支援匯出prometheus metrics 環境準備 docker-compose 檔案

Java語言,基於TCP編寫一個簡單的Client/Server 網路應用程式。

要求實現客戶向伺服器傳輸任意一個字串,伺服器將收到的字串變換成大寫後傳回客戶。//客戶端: package tcpClient; import java.io.BufferedReader; import java.io.DataOutputStream; impo

SQL Server建立應用程式角色與標準角色

 Microsoft® SQL Server™ 中的安全系統在最低級別,即資料庫本身上實現。無論使用什麼應用程式與 SQL Server 通訊,這都是控制使用者活動的最佳方法。但是,有時必須自定義安全控制以適應個別應用程式的特殊需要,尤其是當處理複雜資料庫和含有大表的資料庫時

SQL SERVER觸發器應用案例講解(deleted表或者inserted表)

1、觸發器觸發時:    a、系統自動在記憶體中建立deleted表或者inserted表   b、只讀,不允許修改;觸發器執行完成後,自動刪除 2、inserted表 a、臨時儲存了插入或更新後的記錄行 b、可以從inserted表中檢查插入的資料是否滿足業務需求 c、

live555 server 資料流傳送流程和時間戳的分析

rtsp客戶端傳送播放請求後,rtsp伺服器呼叫流程如下 h264 video rtsp 1.ServerMediaSubsession::startStream ->OnDemandServerMediaSubsession::startStream 2.startStream -> Stre

SQL Server 外圍應用配置器

慢慢悠悠機房收費系統已接近尾聲,在這之前的學生管理系統是順利完成了的,也實現了打包釋出和多臺電腦同時連線伺服器,那時候是用的05版的sql,需要解決的問題就是遠端連線! 05 是這樣實現的:首先, 開啟SQL Server 2005配置工具中的SQL Server conf

數據庫原理及應用(SQL Server 2016數據處理)【上海精品視頻課程】

應用 原理 sql 信息無處不在,數據處理無處不用。物質、信息、能源已經成為人類生存和發展的重要保障。數據庫的應用廣度深度及建設規模已經成為衡量一個國家信息化程度的一項重要標誌。數據庫技術是計算機學科的一個重要分支,反映了數據管理的最新技術。數據庫技術與計算機網絡、人工智能一起被稱為計算機三大

Modbus庫開發筆記之九:利用協議棧開發Modbus TCP Server應用

數根 網絡 received ant getc multiple 利用 這不 tar 前面我們已經完成了Modbus協議棧的開發,但這不是我們的目的。我們開發它的目的當然是要使用它來解決我們的實際問題。接下來我們就使用剛開發的Modbus協議棧開發一個Modbus TCP

數據庫原理與應用 基於SQL Server 2005pdf

數據 數據模型 clear 設計 概念 第7章 漸進 col 理解 下載地址:網盤下載 《數據庫原理與應用 基於SQL Server 2005》介紹數據庫基本原理,並以sql server 2005為平臺介紹數據庫管理系統的應用。全書分為3部分,第l~5章介紹數據庫的一般

SQL Server 2005/2008/2012中應用分布式分區視圖

lag tails soft 9.png .aspx 並且 例如 () 根據   自2000版本起,SQL Server企業版中引入分布式分區視圖,允許你為分布在不同的SQL 實例的兩個或多個水平分區表創建視圖。   簡要步驟如下:根據Check約束中定義的一組值把大表分

Tomcat建立多個應用(Web Server),多個主機,多個站點的方法

-h 制作 ctp 變量 details real def fonts lin https://blog.csdn.net/chungle2011/article/details/52317433 http://piperzero.iteye.com/blog/147577

MSSQL sql server 2005/2008 row_number()函數應用之–刪除表中重

row_number轉自:http://www.maomao365.com/?p=4942 **row_number函數在數據庫中的功能是為每一行 按照一定的規則生成一個編號, 我們常常利用這一屬性,對表進行分頁操作, 下文我們將講述采用 row_number函數刪除表中重復數據行** /*建表*/ crea

第五節:SignalR大雜燴(與MVC融合、全局的幾個配置、跨域的應用、C/S程序充當Client和Server)

融合 變化 方法 signalr 以管理員身份運行 cal 大小 整合 ref 一. 說在前面的話   本節主要在前面章節的基礎上補充了幾個簡單的知識點,比如:第三方調用通過 GlobalHost.ConnectionManager.GetHubContext<

SQL Server WITH ROLLUP、WITH CUBE、GROUPING語句的應用

toolbar then span 分組 table bsp group 生成 spa CUBE:CUBE 生成的結果集顯示了所選列中值的所有組合的聚合。 ROLLUP:ROLLUP 生成的結果集顯示了所選列中值的某一層次結構的聚合。 GROUPING:當行由 CUBE 或

SQL Server DATEADD() 函數及實際項目應用註意事項

時間 參數 數據 part server rom table 們的 nbsp 1. DATEADD() 函數的解釋和語法分析 DATEADD() 函數在日期中添加或減去指定的時間間隔。 語法: DATEADD(datepart,number,date) date 參數是

解決win-server 2008R2 安裝 Materials 出現 Windows Install Coordinator “應用程式正在為首次安裝做準備”

參考 http://muchong.com/bbs/url.php?s=aHR0cHM6Ly93d3cuYnRlcnJlbGwuY29tL0Jsb2cvYmlkLzEwNDg1My9SZXNvbHZpbmctV2luZG93cy1JbnN0YWxsZXItQ29vcmRpbmF0b3Itb24tVGVybWl

web伺服器&應用伺服器(Apache、Tomcat、nginx) Apache HTTP Server,我們常常稱之為httpd,即常說的Apache。它是目前最流行的web伺服器。

現在也沒有特別搞懂他們之間的區別,只是有個大概的理解,可能會有不對的地方,隨時更新吧。 前提得搞明白代理伺服器和反向代理伺服器的區別。 一、web伺服器 Apache HTTP Server,我們常常稱之為httpd,即常說的Apache。它是目前最流行的web伺服器。 Apache

SQL Server 2008中SQL應用系列及BI學習筆記系列--目錄索引

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!