Logo Search packages:      
Sourcecode: blender version File versions  Download package

int av_read_frame ( AVFormatContext *  s,
AVPacket *  pkt 
)

Return the next frame of a stream.

The returned packet is valid until the next av_read_frame() or until av_close_input_file() and must be freed with av_free_packet. For video, the packet contains exactly one frame. For audio, it contains an integer number of frames if each frame has a known fixed size (e.g. PCM or ADPCM data). If the audio frames have a variable size (e.g. MPEG audio), then it contains one frame.

pkt->pts, pkt->dts and pkt->duration are always set to correct values in AV_TIME_BASE unit (and guessed if the format cannot provided them). pkt->pts can be AV_NOPTS_VALUE if the video format has B frames, so it is better to rely on pkt->dts if you do not decompress the payload.

Returns:
0 if OK, < 0 if error or end of file.

Definition at line 982 of file utils.c.

References av_free().

Referenced by av_build_index_raw().

{
    AVPacketList *pktl;
    int eof=0;
    const int genpts= s->flags & AVFMT_FLAG_GENPTS;

    for(;;){
        pktl = s->packet_buffer;
        if (pktl) {
            AVPacket *next_pkt= &pktl->pkt;

            if(genpts && next_pkt->dts != AV_NOPTS_VALUE){
                while(pktl && next_pkt->pts == AV_NOPTS_VALUE){
                    if(   pktl->pkt.stream_index == next_pkt->stream_index
                       && next_pkt->dts < pktl->pkt.dts
                       && pktl->pkt.pts != pktl->pkt.dts //not b frame
                       /*&& pktl->pkt.dts != AV_NOPTS_VALUE*/){
                        next_pkt->pts= pktl->pkt.dts;
                    }
                    pktl= pktl->next;
                }
                pktl = s->packet_buffer;
            }

            if(   next_pkt->pts != AV_NOPTS_VALUE
               || next_pkt->dts == AV_NOPTS_VALUE
               || !genpts || eof){
                /* read packet from packet buffer, if there is data */
                *pkt = *next_pkt;
                s->packet_buffer = pktl->next;
                av_free(pktl);
                return 0;
            }
        }
        if(genpts){
            AVPacketList **plast_pktl= &s->packet_buffer;
            int ret= av_read_frame_internal(s, pkt);
            if(ret<0){
                if(pktl && ret != -EAGAIN){
                    eof=1;
                    continue;
                }else
                    return ret;
            }

            /* duplicate the packet */
            if (av_dup_packet(pkt) < 0)
                return AVERROR_NOMEM;

            while(*plast_pktl) plast_pktl= &(*plast_pktl)->next; //FIXME maybe maintain pointer to the last?

            pktl = av_mallocz(sizeof(AVPacketList));
            if (!pktl)
                return AVERROR_NOMEM;

            /* add the packet in the buffered packet list */
            *plast_pktl = pktl;
            pktl->pkt= *pkt;
        }else{
            assert(!s->packet_buffer);
            return av_read_frame_internal(s, pkt);
        }
    }
}


Generated by  Doxygen 1.6.0   Back to index