ffmpeg(10) mpegts_read_header part 2
来源:互联网 发布:足球球员数据统计 编辑:程序博客网 时间:2024/05/17 22:31
static int mpegts_read_header(AVFormatContext *s)
--->
// 向ts->pids中注册pid为SDT_PID的packet的回调函数
mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1);
// 向ts->pids中注册pid为PAT_PID的packet的回调函数
mpegts_open_section_filter(ts, PAT_PID, pat_cb, ts, 1);
--->
handle_packets(ts, s->probesize / ts->raw_packet_size);
--->
for (;;)
{
printf("%s : %s : %d, packet_num is: %ld\n", __FILE__, __FUNCTION__, __LINE__, packet_num);
packet_num++;
if (nb_packets != 0 && packet_num >= nb_packets || ts->stop_parse > 1)
{
ret = AVERROR(EAGAIN);
break;
}
if (ts->stop_parse > 0)
break;
// 每次读取ts->raw_packet_size个字节到*data指向的内存区域中,ts->raw_packet_size的值应该是一个标准TS packet的大小,即188字节
ret = read_packet(s, packet, ts->raw_packet_size, &data);
if (ret != 0)
break;
// 数据读取到*data中后,调用handle_packet对读取到的数据进行处理
ret = handle_packet(ts, data);
finished_reading_packet(s, ts->raw_packet_size);
if (ret != 0)
break;
}
在函数
/* handle one TS packet */
static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
在这个函数中,
if (ts->auto_guess && tss == NULL && is_start)
{
add_pes_stream(ts, pid, -1);
tss = ts->pids[pid];
}
需要注意,如果ts->auto_guess为1,则所有的pid都会去分析,寻找pes;
is_start 则是来自payload_unit_start_indicator,这一位的定义非常重要:
payload_unit_start_indicator– The payload_unit_start_indicator is a 1-bit flag which has normative meaning for
Transport Stream packets that carry PES packets (refer to 2.4.3.6) or PSI data (refer to 2.4.4).
When the payload of the Transport Stream packet contains PES packet data, the payload_unit_start_indicator has the
following significance: a '1' indicates that the payload of this Transport Stream packet will commence with the first byte
of a PES packet and a '0' indicates no PES packet shall start in this Transport Stream packet. If the
payload_unit_start_indicator is set to '1', then one and only one PES packet starts in this Transport Stream packet. This
also applies to private streams of stream_type 6 (refer to Table 2-29).
When the payload of the Transport Stream packet contains PSI data, the payload_unit_start_indicator has the following
significance: if the Transport Stream packet carries the first byte of a PSI section, the payload_unit_start_indicator value
shall be '1', indicating that the first byte of the payload of this Transport Stream packet carries the pointer_field. If the
Transport Stream packet does not carry the first byte of a PSI section, the payload_unit_start_indicator value shall be '0',
indicating that there is no pointer_field in the payload. Refer to 2.4.4.1 and 2.4.4.2. This also applies to private streams of
stream_type 5 (refer to Table 2-29).
For null packets the payload_unit_start_indicator shall be set to '0'.
在开始时,ts->pids中,只有PAT 和 SDT的 pid Filter不是null,因此其它的数据全部抛弃,只处理PAT 和 SDT packet中的数据:
if (tss->type == MPEGTS_SECTION)
{
if (is_start)
{
/* pointer field present */
len = *p++;
if (p + len > p_end)
return 0;
if (len && cc_ok)
{
/* write remaining section bytes */
write_section_data(s, tss,
p, len, 0);
/* check whether filter has been closed */
if (!ts->pids[pid])
return 0;
}
p += len;
if (p < p_end)
{
write_section_data(s, tss,
p, p_end - p, 1);
}
}
else
{
if (cc_ok)
{
write_section_data(s, tss,
p, p_end - p, 0);
}
}
// stop find_stream_info from waiting for more streams
// when all programs have received a PMT
if (ts->stream->ctx_flags & AVFMTCTX_NOHEADER)
{
int i;
for (i = 0; i < ts->nb_prg; i++)
{
if (!ts->prg[i].pmt_found)
break;
}
if (i == ts->nb_prg && ts->nb_prg > 0)
{
if (ts->stream->nb_streams > 1 || pos > 100000)
{
av_log(ts->stream, AV_LOG_DEBUG, "All programs have pmt, headers found\n");
ts->stream->ctx_flags &= ~AVFMTCTX_NOHEADER;
}
}
}
}
调用函数
static void write_section_data(AVFormatContext *s, MpegTSFilter *tss1,
const uint8_t *buf, int buf_size, int is_start)
将数据写入到对应的pid Filter中的uint8_t *section_buf; 中;
然后调用pid Filter中的callback函数处理section_buf中的数据:
if (crc_valid)
tss->section_cb(tss1, tss->section_buf, tss->section_h_size);
以PAT为例子,在
static int mpegts_read_header(AVFormatContext *s);
中,将static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) 函数
赋值给 PAT_PID Filter的section_cb,因此,此处调用这个函数,处理写入到
section_buf中的数据:
待续~
- ffmpeg(10) mpegts_read_header part 2
- ffmpeg(9) mpegts_read_header
- ffmpeg中sws_scale()用法实例---part of FFmpeg
- FFmpeg 源码分析 Part Two:重要的结构体
- PHP 10问——PART 2
- AngularJS(Part 10)
- J2EE clustering part 2
- Appfuse part 2
- Kerberos Part 2
- 55 Origami Part 2
- Inside ObjectBuilder Part 2
- LESSON 1 -part 2
- Inside ObjectBuilder Part 2
- Inside ObjectBuilder Part 2
- Inside ObjectBuilder Part 2
- Inside ObjectBuilder Part 2
- Inside ObjectBuilder Part 2
- Inside ObjectBuilder Part 2
- 电商实训四:网络营销方案设计及实施
- cocos2d-x 3.0 引用第三方库 及编译成apk时android mk文件写法
- [LeetCode9]Best Time to Buy and Sell Stock II
- UI中图片的完美放大
- centos6.5搭建apache+mysql+php环境
- ffmpeg(10) mpegts_read_header part 2
- httpd-2.4.x 版本客户端访问控制
- pythoner
- 字符串元素重排高效算法集合
- android异常处理概述
- 百度之星2010复赛第二场第三题《蜗牛》
- traits:Traits技术初探
- codeforces 6A Triangle
- Onsctl 配置ONS服务(10G)