音视频入门基础:MPEG2-TS专题(13)——FFmpeg源码中,解析Section Header的实现
一、引言
在《音视频入门基础:MPEG2-TS专题(11)—— TS中的Section》中讲述了Section Header的基本概念,本文讲述FFmpeg源码中是怎样解析Section Header的。
二、parse_section_header函数的定义
FFmpeg源码中通过parse_section_header函数解析Section Header,该函数定义FFmpeg源码(本文演示用的FFmpeg源码版本为7.0.1)的源文件libavformat/mpegts.c中:
static int parse_section_header(SectionHeader *h,const uint8_t **pp, const uint8_t *p_end)
{int val;val = get8(pp, p_end);if (val < 0)return val;h->tid = val;*pp += 2;val = get16(pp, p_end);if (val < 0)return val;h->id = val;val = get8(pp, p_end);if (val < 0)return val;h->version = (val >> 1) & 0x1f;h->current_next = val & 0x01;val = get8(pp, p_end);if (val < 0)return val;h->sec_num = val;val = get8(pp, p_end);if (val < 0)return val;h->last_sec_num = val;return 0;
}
形参h:输出型参数,指向一个SectionHeader类型变量。执行parse_section_header函数后,形参h会得到从Section Header中解析出来的属性。
形参pp:输入型参数,执行parse_section_header函数前,*pp指向一个Section的SectionHeader开头;执行parse_section_header函数后,*pp指向该Section的SectionHeader之后的数据。
形参p_end:输入型参数,指向该Section的CRC校验。
返回值:返回0表示解析成功,返回一个负数表示解析失败。
三、parse_section_header函数的内部实现分析
parse_section_header函数中,首先解析出SectionHeader中的table_id属性,赋值给h->tid:
val = get8(pp, p_end);if (val < 0)return val;h->tid = val;
解析出transport_stream_id/program_number属性,赋值给h->id:
*pp += 2;val = get16(pp, p_end);if (val < 0)return val;h->id = val;
解析出version_number属性,赋值给h->version。解析出current_next_indicator属性,赋值给h->current_next:
val = get8(pp, p_end);if (val < 0)return val;h->version = (val >> 1) & 0x1f;h->current_next = val & 0x01;
解析出section_number属性,赋值给h->sec_num:
val = get8(pp, p_end);if (val < 0)return val;h->sec_num = val;
解析出last_section_number属性,赋值给h->last_sec_num:
val = get8(pp, p_end);if (val < 0)return val;h->last_sec_num = val;