MP4 seek狀態 sample讀取流程

2021-07-16 03:39:36 字數 2919 閱讀 2020

前面一篇部落格詳細剖析了正常情況下,按照sample的順序從前往後讀取sample資料的流程,最重要的過程在於對那幾張表的充分利用,將前面那篇部落格的內容搞明白後,接下來的內容其實也很簡單,這篇部落格主要跟蹤,在seek狀態下的,sample內容的讀取,

即任意時間點對應的sampleindex的確定,這裡還需要確定的是關鍵幀的sampleindex

,有了sampleindex之後,一切就和前面的部落格流程一致了,所以這篇部落格的重點在於藍色部分。

下面就從**上跟一下整個流程,仍然以mp4檔案為例:

我們知道mp4檔案的讀取最後都會進入到mpeg4extractor類的read函式中,在這個函式中首先就需要判斷標誌位,是否是seek的模式

status_t mpeg4source::read(

mediabuffer **out, const readoptions *options) else if (req_time > centertime) else

這個if功能類似於類中的singleton,只會初始化一次,初始化之後在進來就直接return了,提高了效率

msampletimeentries = new sampletimeentry[mnumsamplesizes];

建立乙個陣列,陣列大小為sample的個數,陣列的內容為乙個結構體,結構體的定義如下:

******************************************

struct sampletimeentry else if (start_sample_index > x) else {

left = center;

break;

if (left == mnumsyncsamples) {

if (flags == kflagafter) {

aloge("tried to find a sync frame after the last one: %d", left);

return error_out_of_range;

left = left - 1;

// now ssi[left] is the sync sample index just before (or at)

// start_sample_index.

// also start_sample_index < ssi[left + 1], if left + 1 < mnumsyncsamples.

uint32_t x = msyncsamples[left];

if (left + 1 < mnumsyncsamples) {

uint32_t y = msyncsamples[left + 1];

// our sample lies between sync samples x and y.

status_t err = msampleiterator->seekto(start_sample_index);

if (err != ok) {

return err;

uint32_t sample_time = msampleiterator->getsampletime();

err = msampleiterator->seekto(x);

if (err != ok) {

return err;

uint32_t x_time = msampleiterator->getsampletime();

err = msampleiterator->seekto(y);

if (err != ok) {

return err;

uint32_t y_time = msampleiterator->getsampletime();

if (abs_difference(x_time, sample_time)

> abs_difference(y_time, sample_time)) {

// pick the sync sample closest (timewise) to the start-sample.

x = y;

++left;

switch (flags) {

case kflagbefore:

if (x > start_sample_index) {

check(left > 0);

x = msyncsamples[left - 1];

if (x > start_sample_index) {

// the table of sync sample indices was not sorted

// properly.

return error_malformed;

break;

case kflagafter:

if (x < start_sample_index) {

if (left + 1 >= mnumsyncsamples) {

return error_out_of_range;

x = msyncsamples[left + 1];

if (x < start_sample_index) {

// the table of sync sample indices was not sorted

// properly.

return error_malformed;

break;

default:

break;

上面一段是微調,找到最接近的syncsampleindex

*sample_index = x;

return ok;

到此,找到了相對於seektimeus最近的乙個關鍵幀對應的syncsampleindex,將這個值賦值給mcurrentsampleindex,然後去解析offset和size。

over.

MP4結構分析

一 mp4 mp4 mpeg 4 part14 是一種常見的多 容器格式,是在 iso iec 14496 14 標準檔案中定義的。mp4檔案的所有資料都裝在box quicktime中為atom 中,mp4檔案由若干個box組成,每個box有型別和長度,可以將box理解為乙個資料物件塊。box中可...

nginx支援MP4模組

nginx的安裝參考 安裝步驟 解壓。注釋掉解壓目錄下src ngx http streaming module.c檔案的158 161行的 如下圖。跳轉到nginx解壓目錄,配置安裝mp4模組支援。configure prefix server nginx add module nginx mod...

CLI mp4box 分割合併mp4

分割mp4box split time sec foo.mp4 按照時間分割mp4檔案 mp4box split size sizefoo.mp4 按照檔案大小分割mp4檔案,單位是kb mp4box split chunk s e foo.mp4 切出影片中指定的某段時間 合併 mp4box ca...