分析av_read_frame、av_read_frame_internal和av_read_packet的主要步驟
阿新 • • 發佈:2019-01-27
/*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 */