首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 媒体动画 > 多媒体 >

请问:ffplay里面的一段代码

2013-01-07 
请教:ffplay里面的一段代码ffplay里面有一段代码,不是很明白,代码如下:static int audio_decode_frame(Vid

请教:ffplay里面的一段代码
ffplay里面有一段代码,不是很明白,代码如下:


static int audio_decode_frame(VideoState *is, uint8_t *audio_buf, int buf_size, double *pts_ptr)
{
    AVPacket *pkt = &is->audio_pkt;
    int n, len1, data_size;
    double pts;

    for(;;) {
        /* NOTE: the audio packet can contain several frames */
        while (is->audio_pkt_size > 0) {
            data_size = buf_size;
            len1 = avcodec_decode_audio2(is->audio_st->codec,
                                        (int16_t *)audio_buf, &data_size,
                                        is->audio_pkt_data, is->audio_pkt_size);
            if (len1 < 0) {
                /* if error, we skip the frame */
                is->audio_pkt_size = 0;
                break;
            }

            is->audio_pkt_data += len1;
            is->audio_pkt_size -= len1;
            if (data_size <= 0)
                continue;  // ??? 这里为什么用continue
            /* if no pts, then compute it */
            pts = is->audio_clock;
            *pts_ptr = pts;
            n = 2 * is->audio_st->codec->channels;
            is->audio_clock += (double)data_size /
                (double)(n * is->audio_st->codec->sample_rate);
#if defined(DEBUG_SYNC)
            {
                static double last_clock;
                printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
                       is->audio_clock - last_clock,


                       is->audio_clock, pts);
                last_clock = is->audio_clock;
            }
#endif
            return data_size;
        }

        /* free the current packet */
        if (pkt->data)
            av_free_packet(pkt);

        if (is->paused || is->audioq.abort_request) {
            return -1;
        }

        /* read next packet */
        if (packet_queue_get(&is->audioq, pkt, 1) < 0)
            return -1;
        if(pkt->data == flush_pkt.data){
            avcodec_flush_buffers(is->audio_st->codec);
            continue;
        }

        is->audio_pkt_data = pkt->data;
        is->audio_pkt_size = pkt->size;

        /* if update the audio clock with the pts */
        if (pkt->pts != AV_NOPTS_VALUE) {
            is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
        }
    }
}


这段代码是解码音频的,我不明白的地方已经在代码中标出。就是那个地方为什么要用continue?实在想不明白。
[解决办法]
1、数据量不够了。
2、解码出错。
这时len1 < 0。

只要is->audio_pkt_size > 0,就必须继续给解码器喂数据。

while (is->audio_pkt_size > 0)
说明解码器还没有完全消费掉输入的数据。

[解决办法]
  /* NOTE: the audio packet can contain several frames */


说明一个PACKET里面可能含有多个frame,所以有可能调用多次avcodec_decode_audio2,所以这里是一个循环,

while (is->audio_pkt_size > 0) {
            data_size = buf_size;
            len1 = avcodec_decode_audio2(is->audio_st->codec,
                                        (int16_t *)audio_buf, &data_size,
                                        is->audio_pkt_data, is->audio_pkt_size);


            if (len1 < 0) {
                /* if error, we skip the frame */
                is->audio_pkt_size = 0;
                break;
            }

            is->audio_pkt_data += len1;
            is->audio_pkt_size -= len1;
            if (data_size <= 0)
                continue;  

[解决办法]
data_size是解码器输出数据长度,若为0,说明解码器
无数据输出,那就继续给解码器输入数据。

热点排行