ijkplayer中解析sps的代码,加上ffmpeg中的一部分处理

使用get_resolution_from_sps来获取获取解析到的视频宽高信息

或者其他什么sps中的字段值,在sps_info_struct结构中定义

/*

* h264_sps_parser.h

*

* Copyright (c) 2014 Zhou Quan

*

* This file is part of ijkPlayer.

*

* ijkPlayer is free software; you can redistribute it and/or

* modify it under the terms of the GNU Lesser General Public

* License as published by the Free Software Foundation; either

* version 2.1 of the License, or (at your option) any later version.

*

* ijkPlayer is distributed in the hope that it will be useful,

* but WITHOUT ANY WARRANTY; without even the implied warranty of

* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU

* Lesser General Public License for more details.

*

* You should have received a copy of the GNU Lesser General Public

* License along with ijkPlayer; if not, write to the Free Software

* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

*/

#ifndef IJKMediaPlayer_h264_sps_parser_h

#define IJKMediaPlayer_h264_sps_parser_h

#include

#include

static const uint8_t default_scaling4[2][16] = {

{ 6, 13, 20, 28, 13, 20, 28, 32,

20, 28, 32, 37, 28, 32, 37, 42 },

{ 10, 14, 20, 24, 14, 20, 24, 27,

20, 24, 27, 30, 24, 27, 30, 34 }

};

static const uint8_t default_scaling8[2][64] = {

{ 6, 10, 13, 16, 18, 23, 25, 27,

10, 11, 16, 18, 23, 25, 27, 29,

13, 16, 18, 23, 25, 27, 29, 31,

16, 18, 23, 25, 27, 29, 31, 33,

18, 23, 25, 27, 29, 31, 33, 36,

23, 25, 27, 29, 31, 33, 36, 38,

25, 27, 29, 31, 33, 36, 38, 40,

27, 29, 31, 33, 36, 38, 40, 42 },

{ 9, 13, 15, 17, 19, 21, 22, 24,

13, 13, 17, 19, 21, 22, 24, 25,

15, 17, 19, 21, 22, 24, 25, 27,

17, 19, 21, 22, 24, 25, 27, 28,

19, 21, 22, 24, 25, 27, 28, 30,

21, 22, 24, 25, 27, 28, 30, 32,

22, 24, 25, 27, 28, 30, 32, 33,

24, 25, 27, 28, 30, 32, 33, 35 }

};

static const uint8_t ff_zigzag_direct[64] = {

0, 1, 8, 16, 9, 2, 3, 10,

17, 24, 32, 25, 18, 11, 4, 5,

12, 19, 26, 33, 40, 48, 41, 34,

27, 20, 13, 6, 7, 14, 21, 28,

35, 42, 49, 56, 57, 50, 43, 36,

29, 22, 15, 23, 30, 37, 44, 51,

58, 59, 52, 45, 38, 31, 39, 46,

53, 60, 61, 54, 47, 55, 62, 63

};

static const uint8_t ff_zigzag_scan[16+1] = {

0 + 0 * 4, 1 + 0 * 4, 0 + 1 * 4, 0 + 2 * 4,

1 + 1 * 4, 2 + 0 * 4, 3 + 0 * 4, 2 + 1 * 4,

1 + 2 * 4, 0 + 3 * 4, 1 + 3 * 4, 2 + 2 * 4,

3 + 1 * 4, 3 + 2 * 4, 2 + 3 * 4, 3 + 3 * 4,

};

typedef struct

{

const uint8_t *data;

const uint8_t *end;

int head;

uint64_t cache;

} nal_bitstream;

static void

nal_bs_init(nal_bitstream *bs, const uint8_t *data, size_t size)

{

bs->data = data;

bs->end = data + size;

bs->head = 0;

// fill with something other than 0 to detect

// emulation prevention bytes

bs->cache = 0xffffffff;

}

static uint64_t

nal_bs_read(nal_bitstream *bs, int n)

{

uint64_t res = 0;

int shift;

if (n == 0)

return res;

// fill up the cache if we need to

while (bs->head < n) {

uint8_t a_byte;

bool check_three_byte;

check_three_byte = true;

next_byte:

if (bs->data >= bs->end) {

// we're at the end, can't produce more than head number of bits

n = bs->head;

break;

}

// get the byte, this can be an emulation_prevention_three_byte that we need

// to ignore.

a_byte = *bs->data++;

if (check_three_byte && a_byte == 0x03 && ((bs->cache & 0xffff) == 0)) {

// next byte goes unconditionally to the cache, even if it's 0x03

check_three_byte = false;

goto next_byte;

}

// shift bytes in cache, moving the head bits of the cache left

bs->cache = (bs->cache << 8) | a_byte;

bs->head += 8;

}

// bring the required bits down and truncate

if ((shift = bs->head - n) > 0)

res = bs->cache >> shift;

else

res = bs->cache;

// mask out required bits

if (n < 32)

res &= (1 << n) - 1;

bs->head = shift;

return res;

}

static bool

nal_bs_eos(nal_bitstream *bs)

{

return (bs->data >= bs->end) && (bs->head == 0);

}

// read unsigned Exp-Golomb code

static int64_t

nal_bs_read_ue(nal_bitstream *bs)

{

int i = 0;

while (nal_bs_read(bs, 1) == 0 && !nal_bs_eos(bs) && i < 32)

i++;

return ((1 << i) - 1 + nal_bs_read(bs, i));

}

//解码有符号的指数哥伦布编码

static int64_t

nal_bs_read_se(nal_bitstream *bs)

{

int64_t ueVal = nal_bs_read_ue(bs);

double k = ueVal;

int64_t nValue = ceil(k/2);

if(ueVal%2 == 0)

{

nValue = -nValue;

}

return nValue;

}

typedef struct

{

uint64_t profile_idc;

uint64_t level_idc;

uint64_t sps_id;

uint64_t chroma_format_idc;

uint64_t separate_colour_plane_flag;

uint64_t bit_depth_luma_minus8;

uint64_t bit_depth_chroma_minus8;

uint64_t qpprime_y_zero_transform_bypass_flag;

uint64_t seq_scaling_matrix_present_flag;

uint64_t log2_max_frame_num_minus4;

uint64_t pic_order_cnt_type;

uint64_t log2_max_pic_order_cnt_lsb_minus4;

uint64_t max_num_ref_frames;

uint64_t gaps_in_frame_num_value_allowed_flag;

uint64_t pic_width_in_mbs_minus1;

uint64_t pic_height_in_map_units_minus1;

uint64_t frame_mbs_only_flag;

uint64_t mb_adaptive_frame_field_flag;

uint64_t direct_8x8_inference_flag;

uint64_t frame_cropping_flag;

uint64_t frame_crop_left_offset;

uint64_t frame_crop_right_offset;

uint64_t frame_crop_top_offset;

uint64_t frame_crop_bottom_offset;

} sps_info_struct;

static void decode_scaling_list(nal_bitstream *bs, uint8_t *factors, int size,

const uint8_t *jvt_list,

const uint8_t *fallback_list)

{

int i, last = 8, next = 8;

const uint8_t *scan = size == 16 ? ff_zigzag_scan : ff_zigzag_direct;

if (!nal_bs_read(bs, 1)) /* matrix not written, we use the predicted one */

memcpy(factors, fallback_list, size * sizeof(uint8_t));

else

for (i = 0; i < size; i++) {

if (next)

next = (last + nal_bs_read_se(bs)) & 0xff;

if (!i && !next) { /* matrix not written, we use the preset one */

memcpy(factors, jvt_list, size * sizeof(uint8_t));

break;

}

last = factors[scan[i]] = next ? next : last;

}

}

static void decode_scaling_matrices(nal_bitstream *bs, sps_info_struct *sps,

void* pps, int is_sps,

uint8_t(*scaling_matrix4)[16],

uint8_t(*scaling_matrix8)[64])

{

int fallback_sps = !is_sps && sps->seq_scaling_matrix_present_flag;

const uint8_t *fallback[4] = {

fallback_sps ? scaling_matrix4[0] : default_scaling4[0],

fallback_sps ? scaling_matrix4[3] : default_scaling4[1],

fallback_sps ? scaling_matrix8[0] : default_scaling8[0],

fallback_sps ? scaling_matrix8[3] : default_scaling8[1]

};

if (nal_bs_read(bs, 1)) {

sps->seq_scaling_matrix_present_flag |= is_sps;

decode_scaling_list(bs, scaling_matrix4[0], 16, default_scaling4[0], fallback[0]); // Intra, Y

decode_scaling_list(bs, scaling_matrix4[1], 16, default_scaling4[0], scaling_matrix4[0]); // Intra, Cr

decode_scaling_list(bs, scaling_matrix4[2], 16, default_scaling4[0], scaling_matrix4[1]); // Intra, Cb

decode_scaling_list(bs, scaling_matrix4[3], 16, default_scaling4[1], fallback[1]); // Inter, Y

decode_scaling_list(bs, scaling_matrix4[4], 16, default_scaling4[1], scaling_matrix4[3]); // Inter, Cr

decode_scaling_list(bs, scaling_matrix4[5], 16, default_scaling4[1], scaling_matrix4[4]); // Inter, Cb

if (is_sps) {

decode_scaling_list(bs, scaling_matrix8[0], 64, default_scaling8[0], fallback[2]); // Intra, Y

decode_scaling_list(bs, scaling_matrix8[3], 64, default_scaling8[1], fallback[3]); // Inter, Y

if (sps->chroma_format_idc == 3) {

decode_scaling_list(bs, scaling_matrix8[1], 64, default_scaling8[0], scaling_matrix8[0]); // Intra, Cr

decode_scaling_list(bs, scaling_matrix8[4], 64, default_scaling8[1], scaling_matrix8[3]); // Inter, Cr

decode_scaling_list(bs, scaling_matrix8[2], 64, default_scaling8[0], scaling_matrix8[1]); // Intra, Cb

decode_scaling_list(bs, scaling_matrix8[5], 64, default_scaling8[1], scaling_matrix8[4]); // Inter, Cb

}

}

}

}

static void parseh264_sps(sps_info_struct* sps_info, uint8_t* sps_data, uint32_t sps_size)

{

if(sps_info == NULL)

return;

memset(sps_info, 0, sizeof(sps_info_struct));

uint8_t scaling_matrix4[6][16];

uint8_t scaling_matrix8[6][64];

memset(scaling_matrix4, 16, sizeof(scaling_matrix4));

memset(scaling_matrix8, 16, sizeof(scaling_matrix8));

nal_bitstream bs;

nal_bs_init(&bs, sps_data, sps_size);

sps_info->profile_idc = nal_bs_read(&bs, 8);

nal_bs_read(&bs, 1); // constraint_set0_flag

nal_bs_read(&bs, 1); // constraint_set1_flag

nal_bs_read(&bs, 1); // constraint_set2_flag

nal_bs_read(&bs, 1); // constraint_set3_flag

nal_bs_read(&bs, 4); // reserved

sps_info->level_idc = nal_bs_read(&bs, 8);

sps_info->sps_id = nal_bs_read_ue(&bs);

if (sps_info->profile_idc == 100 ||

sps_info->profile_idc == 110 ||

sps_info->profile_idc == 122 ||

sps_info->profile_idc == 244 ||

sps_info->profile_idc == 44 ||

sps_info->profile_idc == 83 ||

sps_info->profile_idc == 86 ||

sps_info->profile_idc == 118 ||

sps_info->profile_idc == 128 ||

sps_info->profile_idc == 138 ||

sps_info->profile_idc == 144)

{

sps_info->chroma_format_idc = nal_bs_read_ue(&bs);

if (sps_info->chroma_format_idc == 3)

sps_info->separate_colour_plane_flag = nal_bs_read(&bs, 1);

sps_info->bit_depth_luma_minus8 = nal_bs_read_ue(&bs);

sps_info->bit_depth_chroma_minus8 = nal_bs_read_ue(&bs);

sps_info->qpprime_y_zero_transform_bypass_flag = nal_bs_read(&bs, 1);

// sps_info->seq_scaling_matrix_present_flag = nal_bs_read (&bs, 1);

decode_scaling_matrices(&bs, sps_info, NULL, 1, scaling_matrix4, scaling_matrix8);

}

sps_info->log2_max_frame_num_minus4 = nal_bs_read_ue(&bs);

if (sps_info->log2_max_frame_num_minus4 > 12) {

// must be between 0 and 12

// don't early return here - the bits we are using (profile/level/interlaced/ref frames)

// might still be valid - let the parser go on and pray.

//return;

}

sps_info->pic_order_cnt_type = nal_bs_read_ue(&bs);

if (sps_info->pic_order_cnt_type == 0) {

sps_info->log2_max_pic_order_cnt_lsb_minus4 = nal_bs_read_ue(&bs);

}

else if (sps_info->pic_order_cnt_type == 1) {

nal_bs_read(&bs, 1); //delta_pic_order_always_zero_flag

nal_bs_read_se(&bs); //offset_for_non_ref_pic

nal_bs_read_se(&bs); //offset_for_top_to_bottom_field

int64_t num_ref_frames_in_pic_order_cnt_cycle = nal_bs_read_ue(&bs);

for(int i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++ )

{

nal_bs_read_se(&bs); //int offset_for_ref_frame =

}

}

sps_info->max_num_ref_frames = nal_bs_read_ue(&bs);

sps_info->gaps_in_frame_num_value_allowed_flag = nal_bs_read(&bs, 1);

sps_info->pic_width_in_mbs_minus1 = nal_bs_read_ue(&bs);

sps_info->pic_height_in_map_units_minus1 = nal_bs_read_ue(&bs);

sps_info->frame_mbs_only_flag = nal_bs_read(&bs, 1);

if (!sps_info->frame_mbs_only_flag)

sps_info->mb_adaptive_frame_field_flag = nal_bs_read(&bs, 1);

sps_info->direct_8x8_inference_flag = nal_bs_read(&bs, 1);

sps_info->frame_cropping_flag = nal_bs_read(&bs, 1);

if (sps_info->frame_cropping_flag) {

sps_info->frame_crop_left_offset = nal_bs_read_ue(&bs);

sps_info->frame_crop_right_offset = nal_bs_read_ue(&bs);

sps_info->frame_crop_top_offset = nal_bs_read_ue(&bs);

sps_info->frame_crop_bottom_offset = nal_bs_read_ue(&bs);

}

}

static void get_resolution_from_sps(uint8_t* sps, uint32_t sps_size, uint64_t* width, uint64_t* height)

{

sps_info_struct sps_info = {0};

parseh264_sps(&sps_info, sps, sps_size);

*width = (sps_info.pic_width_in_mbs_minus1 + 1) * 16 - sps_info.frame_crop_left_offset * 2 - sps_info.frame_crop_right_offset * 2;

*height = ((2 - sps_info.frame_mbs_only_flag) * (sps_info.pic_height_in_map_units_minus1 + 1) * 16) - sps_info.frame_crop_top_offset * 2 - sps_info.frame_crop_bottom_offset * 2;

}

#endif

java h264 sps解码,H264 SPS解析相关推荐

  1. [H264编解码参数] SPS

    #前言 RTP完整流程 已经 解释了协议 所以要涉及具体的log分析 分为: SPS \ PPS\I帧\非I帧\FU-A SPS 序列参数集合 SPS 属于 [RTP header] + 单一NAL单 ...

  2. H264编解码SPS、PPS参数说明

    H264编解码参数说明 一.H264码流分层 1.NAL层 ①.如何判断帧类型(是图像参考帧还是I.P帧等)? ②. 帧格式 ③. [SPS格式解析代码分析 ParseAndRewriteSps方法 ...

  3. H264帧的分析sps pps

    帧格式 H264帧由NALU头和NALU主体组成. NALU头由一个字节组成,它的语法如下: +---------------+       |0|1|2|3|4|5|6|7|       +-+-+ ...

  4. H264码流中SPS、PPS详解

    1 SPS和PPS从何处而来? 2 SPS和PPS中的每个参数起什么作用? 3 如何解析SDP中包含的H.264的SPS和PPS串? 1 客户端抓包 在做客户端视频解码时,一般都会使用Wireshar ...

  5. 从RTSP协议SDP数据中获得H264中的的SPS、PPS

    1. 如何解析SDP中包含的H.264的SPS和PPS串 SDP中的H.264的SPS和PPS串,包含了初始化H.264解码器所需要的信息参数,包括编码所用的profile,level,图像的宽和高, ...

  6. H264码流中SPS的获取

    The h.264 Sequence Parameter Set April 20th, 2011 by Ben Mesander 此文对于想要了解如何获取h264码流中SPS参数的过程,但是又不是很 ...

  7. H264分辨率解码概述

    目录 1. 申明 2. 目的 3. 背景知识 3.1 哥伦比亚指数编码无符号数的解码 3.2 哥伦比亚指数编码有符号数的解码 3.3 解析参数序列集的过程 4. 代码demo 5. 专栏知识链接 6. ...

  8. 视频的基本参数及H264编解码相关概念

    概述 上几篇文章介绍了音频的采集以及编码,现在我们开始学习视频相关的知识,同样先从概念开始.本篇文章的主要内容有: 视频相关参数 帧率(fps) 分辨率 DTS和PTS 码率 音视频同步 对视频编解码 ...

  9. H264及H265 I帧解析 [转]

    H264及H265 I帧解析 [转] h264 I帧的判断 参考原文:https://blog.csdn.net/dxpqxb/article/details/13289205?utm_source= ...

最新文章

  1. Linux Centos7 下安装Mysql - 8.0.15
  2. Web前端技术分享:img标签下方出现空隙的问题解决方案
  3. Error establishing a database connection!
  4. HttpClientFactory 结合 Polly 轻松实现重试机制
  5. Java Maven和Gradle构建的主题缓存
  6. numpy细碎知识点
  7. 如何检测支付宝接口中notify_url.php有没有返回,微信小程序支付成功,但是notify_url接收不到回调如何排查此问题?...
  8. dgi数据治理_国外数据治理模型比较
  9. 除手机平板PC外 华为终端明年全线搭载鸿蒙系统
  10. php 可编辑菜单,菜单的添加编辑
  11. (转)软件开发和团队”最小模式”初探2-6人模型(下)
  12. SSH三大框架的概述
  13. CVE-2018-14418 擦出新火花
  14. 懒人神器——新手必备的图片后期处理软件
  15. MSN登陆以后没有响应处理方法
  16. FreeBSD常用操作
  17. python播放全网视频+打包成exe
  18. open drain和push pull
  19. calibre版本问题造成无法转换pdf
  20. 基于STM32的OLED 屏幕驱动

热门文章

  1. 《CSDN云原生工程师能力认证——IT人才进名企的牵引者》
  2. 自适应学习率算法.基于阿米霍步长准则的线性回溯搜索算法
  3. CV 经典主干网络 (Backbone) 系列: CSPNet
  4. QT入门Input Widgets之QFontComboBox、QTextEdit、QPlainTextEdit、QDial、QKeySequenceEdit
  5. T-S型模糊算法简述及FPGA的实现
  6. 速看 2021-2022年23项重大网络犯罪统计数据
  7. CUMT矿大----电路与数字系统实验四 计数、译码、显示的HDL设计
  8. IntelliJ 使用Maven构建Android项目过程
  9. 盘点大厂的那些开源项目 - 滴滴出行
  10. 内存空间管理---连续