现在的位置: 首页 > 综合 > 正文

分析av_read_frame、av_read_frame_internal和av_read_packet的主要步骤

2014年01月18日 ⁄ 综合 ⁄ 共 2373字 ⁄ 字号 评论关闭
/*av_read_frame
1.先判断缓存[s->packet_buffer, s->packet_buffer_end)中是否存在packet
2.缓存中没有packet时调用av_read_frame_internal
*/
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
{
	pktl = s->packet_buffer;
	if (pktl) 
	{
		AVPacket *next_pkt= &pktl->pkt;
		/* read packet from packet buffer, if there is data */
		*pkt = *next_pkt;
		s->packet_buffer = pktl->next;
		av_free(pktl);
		return 0;
	}

	return av_read_frame_internal(s, pkt);
}

/*av_read_frame_internal
1.先判断缓存s->cur_st->cur_pkt中是否可以再Pasre出packet
2.不能Pasre出packet时调用av_read_packet,并设置到s->cur_st->cur_pkt
*/
static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt)
{
	AVStream *st;
	int len, ret, i;

	av_init_packet(pkt);

	for(;;) 
	{
		/* select current input stream component */
		st = s->cur_st;
		if (st) 
		{
			if (!st->need_parsing || !st->parser) 
			{
				/* no parsing needed: we just output the packet as is */
				/* raw data support */
				*pkt = st->cur_pkt; st->cur_pkt.data= NULL;
				compute_pkt_fields(s, st, NULL, pkt);
				s->cur_st = NULL;
				break;
			} 
			else if (st->cur_len > 0 && st->discard < AVDISCARD_ALL) 
			{
				len = av_parser_parse(st->parser, st->codec, &pkt->data, &pkt->size,
					st->cur_ptr, st->cur_len,
					st->cur_pkt.pts, st->cur_pkt.dts);
				st->cur_pkt.pts = AV_NOPTS_VALUE;
				st->cur_pkt.dts = AV_NOPTS_VALUE;
				/* increment read pointer */
				st->cur_ptr += len;
				st->cur_len -= len;
			}
		} 
		else 
		{
			AVPacket cur_pkt;
			/* read next packet */
			ret = av_read_packet(s, &cur_pkt);

			st = s->streams[cur_pkt.stream_index];
			st->cur_pkt= cur_pkt;

			s->cur_st = st;
			st->cur_ptr = st->cur_pkt.data;
			st->cur_len = st->cur_pkt.size;
		}
	}
	return 0;
}

/*av_read_packet
1.先判断缓存[s->raw_packet_buffer, s->raw_packet_buffer_end)中是否存在packet
2.缓存中没有packet时调用s->iformat->read_packet(s, pkt);
3.调用add_to_pktbuf将packet加入[s->raw_packet_buffer, s->raw_packet_buffer_end)中
*/

int av_read_packet(AVFormatContext *s, AVPacket *pkt)
{
	int ret;
	AVStream *st;

	for(;;)
	{
		AVPacketList *pktl = s->raw_packet_buffer;

		if (pktl) 
		{
			*pkt = pktl->pkt;
			s->raw_packet_buffer = pktl->next;
			av_free(pktl);
			return 0;
		}

		av_init_packet(pkt);

		//如果是AVI format,则最终调用avidec.c的avi_read_packet
		ret= s->iformat->read_packet(s, pkt);
		if (ret < 0)
			return ret;

		add_to_pktbuf(&s->raw_packet_buffer, pkt, &s->raw_packet_buffer_end);
	}
}

/*要点:
1.av_read_frame中缓存的[s->packet_buffer, s->packet_buffer_end)是经过parse后的
2.av_read_packet中缓存的[s->raw_packet_buffer, s->raw_packet_buffer_end)是从源读入的Packet,是Raw Data
3.av_read_frame_internal中parse的是Raw Data的Packet,关键在 len = av_parser_parse(st->parser, st->codec, 
&pkt->data, &pkt->size,	//解析后输出的Packet,应该是one frame
st->cur_ptr, st->cur_len,//从源读入的Raw Data的Packet
st->cur_pkt.pts, st->cur_pkt.dts);
4. s->parser->parser_parse函数是为了从raw packet中重构frame

*/

抱歉!评论已关闭.