如何從H264原始資料SPS裡面得到視訊的長寬
有這樣一種需求,給你一個h264原始資料檔案,讓你直接播放出來,如何實現?
思路是這樣的,H264原始資料格式都是 0x00000001後面跟0x67 0x68 0x65 0x41這樣的資料,解碼需要一個完整的NAL資料單元,我們需要將每個0x00000001以及下一個0x00000001之前的資料讀出來,交給解碼器解碼。
讀檔案我就不囉嗦了,本文主要講解如何從SPS獲取視訊長寬,SPS即0x67開頭資料,讀到0x00000001 後一個位元組是0x67的後面跟的資料就是SPS了。我們看一個封包裡面sps的結構:
我們可以看到 最下面的42開始就是0x67後面的SPS資料了,看H264的官方文件可以知道,SPS裡面的引數都是按照bit的形式儲存的。
我自己寫了一個解析SPS的類,程式碼如下:
只需呼叫如下介面即可得到寬高:import android.util.Log; /* * Author:Vincent Luo * Date: 20150615 * Description:參考H264標準語法實現對SPS引數的解析 */ public class H264SPSPaser { private static final String TAG = "H264SPSPaser"; private static int startBit = 0; /* * 從資料流data中第StartBit位開始讀,讀bitCnt位,以無符號整形返回 */ public static short u(byte[] data,int bitCnt,int StartBit){ short ret = 0; int start = StartBit; for(int i = 0;i < bitCnt;i++){ ret<<=1; if ((data[start / 8] & (0x80 >> (start%8))) != 0) { ret += 1; } start++; } return ret; } /* * 無符號指數哥倫布編碼 * leadingZeroBits = −1; * for( b = 0; !b; leadingZeroBits++ ) * b = read_bits( 1 ) * 變數codeNum 按照如下方式賦值: * codeNum = 2^leadingZeroBits − 1 + read_bits( leadingZeroBits ) * 這裡read_bits( leadingZeroBits )的返回值使用高位在先的二進位制無符號整數表示。 */ public static short ue(byte[] data,int StartBit){ short ret = 0; int leadingZeroBits = -1; int tempStartBit = (StartBit == -1)?startBit:StartBit;//如果傳入-1,那麼就用上次記錄的靜態變數 for( int b = 0; b != 1; leadingZeroBits++ ){//讀到第一個不為0的數,計算前面0的個數 b = u(data,1,tempStartBit++); } Log.d(TAG,"ue leadingZeroBits = " + leadingZeroBits + ",Math.pow(2, leadingZeroBits) = " + Math.pow(2, leadingZeroBits) + ",tempStartBit = " + tempStartBit); ret = (short) (Math.pow(2, leadingZeroBits) - 1 + u(data,leadingZeroBits,tempStartBit)); startBit = tempStartBit + leadingZeroBits; Log.d(TAG,"ue startBit = " + startBit); return ret; } /* * 有符號指數哥倫布編碼 * 9.1.1 有符號指數哥倫布編碼的對映過程 *按照9.1節規定,本過程的輸入是codeNum。 *本過程的輸出是se(v)的值。 *表9-3中給出了分配給codeNum的語法元素值的規則,語法元素值按照絕對值的升序排列,負值按照其絕對 *值參與排列,但列在絕對值相等的正值之後。 *表 9-3-有符號指數哥倫布編碼語法元素se(v)值與codeNum的對應 *codeNum 語法元素值 * 0 0 * 1 1 * 2 −1 * 3 2 * 4 −2 * 5 3 * 6 −3 * k (−1)^(k+1) Ceil( k÷2 ) */ public static int se(byte[] data,int StartBit){ int ret = 0; short codeNum = ue(data,StartBit); ret = (int) (Math.pow(-1, codeNum + 1)*Math.ceil(codeNum/2)); return ret; } }
int width = (H264SPSPaser.ue(sps,34) + 1)*16;
int height = (H264SPSPaser.ue(sps,-1) + 1)*16;
其中引數sps就是42開始的那一串位元組流,34指的是寬開始的位置(bit位)。相關推薦
如何從H264原始資料SPS裡面得到視訊的長寬
有這樣一種需求,給你一個h264原始資料檔案,讓你直接播放出來,如何實現? 思路是這樣的,H264原始資料格式都是 0x00000001後面跟0x67 0x68 0x65 0x41這樣的資料,解碼需要一個完整的NAL資料單元,我們需要將每個0x00000001以及下一個0x
vlc從接收到資料流到播放視訊的過程分析
VLC API documentation 或者VLC developer documentation Chapter 5. The video output layer Data structures and main loop Important data structures ar
嵌入式 vlc從接收到資料流到播放視訊的過程分析
Vlc流播放流程 vlc原始碼目錄樹: 目錄名稱 說明 bindings Java, CIL 和Python繫結 doc 幫助文件 (不是更新的) extras 另敘。 include VLC 標頭檔案 libs SRTP庫和
vlc學習計劃(7)--從接收到資料流到播放視訊的過程分析
從接收到資料流到播放視訊的過程分析 從網路接收到流->對資料流進行視訊和音訊分離->對視訊用解碼器解碼->顯示解碼後的視訊流<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:off
使用 ffmpeg 進行網路推流:拉流->解封裝->解碼->處理原始資料(音訊、視訊)->編碼->編碼->推流
簡要說明: 1、可拉流:rtmp、rtsp、http 2、可推流: #include "stdafx.h" extern "C" { #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #
資料處理--reshape2包(長寬資料)
寬資料 ozone wind temp 1 23.62 11.623 65.55 2 29.44 10.267 79.10 3 59.12 8.942 83.90 4 59.96 8.794 83.97 長資料 variable value 1 ozone 23.
video從遠端獲取資料跳轉新頁面開始播放視訊
效果: 獲取電影資料每行3個 video.html <div id="item-video-animation" class="mui-control-content"> <div id="videoAnimation" style="text-align: cen
從零開始的鐳射通訊(第1章 協議棧)——4、原始資料編解碼
從零開始的鐳射通訊(第1章 協議棧)——4、原始資料編解碼 github 簡介 移動位置法 提取最高位法 函式說明 github https://github.com/HaHaHaHaHaGe/mynet
【備忘】大資料學習從菜鳥到精通學習路線視訊教程
01.第一階段 大資料必備linux基礎與實戰 02.第二階段 大資料hadoop家族架構實戰 03.第三階段 大資料實時分析Storm入門到精通 04.第四階段 新一代大資料Spark平臺實戰 05.第五階段 知名公司大資料專案實戰
RNN文字分類——從原始資料處理到預測類別標籤
這兩天做了一個小專案,是一個文因互聯文字分類的競賽題目,但已經過期了,只是使用它的資料做一下。本次使用的RNN+LSTM模型,最終訓練的正確率為87%,不過每次訓練正確率有些差別,並且還有很多可調引數沒有調整,只是當一個練手的了。由於訓練時間很長,完整的程式碼以
Android 網路請求原理以及原始資料包
我們在請求網路的時候都是使用各種框架,或者是 Android SDK 為我們提供的網路請求類。但是你知不知道原始的網路請求包是什麼樣的呢?或許你說這有什麼作用,我會使用框架就好了。很顯然,這種想法是有問題的。一些網路請求的基本知識我們還是需要掌握的。這對我們更深入的開發和掌握更深的技術是非常有必要的。 關於
tensorflow--從檔案讀取資料
讀取資料-csv tensorflow讀取資料流程 構造檔案佇列 讀取佇列內容 reader = tf.TextLineReader() 解析成一個樣本資料 example, label = tf.decode_csv(value, record_defaults
mysql安裝,以及從csv插入資料
1.mysql安裝 用管理員身份開啟cmd命令列工具,cd到解壓檔案的bin目錄: ・MySql的Windows服務安裝: mysqld install 回車 ・生成無密碼的root使用者: mysqld --initialize-insecure
Python 遍歷資料夾裡面的內容 5*
root_path='./result' sub_path=root_path+'./tmp' for root, dirs, files in os.walk(sub_path): for file in files: if os.path.splitext(file)[
html 裡面鑲嵌視訊,一種是video,一種是iframe
1,解決iframe不能全屏的問題 <iframe style="width:98%;height: 450px;" src='{$vo.url}' frameborder=0 allowfullscreen="true" webkitallowfullscreen="tru
jQueryAjax++servlet+json實現頁面載入時從後臺讀取資料
在eclipse中新建一個專案,我起名為Demo 新建一個html檔案,在其中引入外部jQuery和自定義的js檔案 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <sc
java中從控制檯輸入資料和輸出資料到控制檯
1.從控制檯輸入資料 1.使用Scanner類來完成從命令列輸入資料到自己的程式中。 2.Scanner類是JDK1.5【jdk5.0】新增的一個開發類庫。 3.Scanner類使用 3.1先匯入Scanner類所在的程式包【java.util.Sca
從資料庫查詢資料並輸出到前臺頁面
<?php //獲取資料庫中的所有留言 require_once("connect.php"); &nbs
java學習實驗隨筆-------如何從鍵盤輸入資料並儲存到陣列中
從鍵盤輸入並儲存 public static void main(String[] args) { Scanner reader = new Scanner(System.in); /使用Scanner庫進行輸入操作 int[] a = ne
STM32從模式接受資料
在實際應用中,會碰到上位機往單片機發送資料的情況,這時候需要配置微控制器為從裝置,準備接受資料 使用硬體I2C時,開啟事件和快取中斷 I2C_ITConfig(SLAVER_I2C, I2C_IT_EVT | I2C_IT_BUF, ENABLE); 然後在中斷服務函式中接受資料