Skip to content

Commit

Permalink
avplay.c 缓冲计算
Browse files Browse the repository at this point in the history
  • Loading branch information
microcai committed Dec 2, 2012
1 parent 78cc444 commit d180bf1
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 39 deletions.
81 changes: 44 additions & 37 deletions libav/avplay.c
Original file line number Diff line number Diff line change
Expand Up @@ -1244,6 +1244,7 @@ void* read_pkt_thrd(void *param)
av_seek(play, play->m_start_time);
}

play->m_buffering = 0.0f;
play->m_real_bit_rate = 0;

for (; !play->m_abort;)
Expand Down Expand Up @@ -1338,6 +1339,7 @@ void* read_pkt_thrd(void *param)
/* 更新缓冲字节数. */
pthread_mutex_lock(&play->m_buf_size_mtx);
play->m_pkt_buffer_size += packet.size;
play->m_buffering = (double)play->m_pkt_buffer_size / (double)MAX_PKT_BUFFER_SIZE;
pthread_mutex_unlock(&play->m_buf_size_mtx);

/* 在这里计算码率. */
Expand Down Expand Up @@ -1398,7 +1400,7 @@ static
void* audio_dec_thrd(void *param)
{
AVPacket pkt, pkt2;
int ret, n;
int ret, n, out_size = 0;
AVFrame avframe = { 0 }, avcopy;
avplay *play = (avplay*) param;
int64_t v_start_time = 0;
Expand All @@ -1411,6 +1413,9 @@ void* audio_dec_thrd(void *param)
a_start_time = play->m_audio_st->start_time;
}

avframe.data[0] = av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3);
audio_buf = avframe.data[0];

for (; !play->m_abort;)
{
av_init_packet(&pkt);
Expand Down Expand Up @@ -1446,65 +1451,62 @@ void* audio_dec_thrd(void *param)
pthread_mutex_unlock(&play->m_audio_q.m_mutex);

/* 解码音频. */
out_size = 0;
pkt2 = pkt;
avcodec_get_frame_defaults(&avframe);

avframe.linesize[0] = 0;
while (!play->m_abort)
{
int got_frame = 0;
ret = avcodec_decode_audio4(play->m_audio_ctx, &avframe, &got_frame, &pkt2);
int audio_out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
ret = avcodec_decode_audio3(play->m_audio_ctx,
(int16_t*)((uint8_t*)audio_buf + out_size), &audio_out_size, &pkt2);
if (ret < 0)
{
printf("Audio error while decoding one frame!!!\n");
break;
}
out_size += audio_out_size;
pkt2.size -= ret;
pkt2.data += ret;

if (!got_frame && pkt2.size > 0)
continue;

if (pkt2.size == 0 && !got_frame)
if (pkt2.size <= 0)
break;
}

if (avframe.linesize[0]/*out_size*/ != 0)
{
/* copy并转换音频格式. */
audio_copy(play, &avcopy, &avframe);

/* 将计算的pts复制到avcopy.pts. */
memcpy(&avcopy.pts, &play->m_audio_clock, sizeof(double));
if (out_size > 0)
{
avframe.pts = pkt2.pts;
avframe.best_effort_timestamp = pkt2.pts;
avframe.linesize[0] = out_size;

/* 计算下一个audio的pts值. */
n = 2 * FFMIN(play->m_audio_ctx->channels, 2);
/* 拷贝到avcopy用于添加到队列. */
audio_copy(play, &avcopy, &avframe);

play->m_audio_clock += ((double) avcopy.linesize[0] / (double) (n * play->m_audio_ctx->sample_rate));
/* 将计算的pts复制到avcopy.pts. */
memcpy(&avcopy.pts, &play->m_audio_clock, sizeof(double));

/* 如果不是以音频同步为主, 则需要计算是否移除一些采样以同步到其它方式. */
if (play->m_av_sync_type == AV_SYNC_EXTERNAL_CLOCK ||
play->m_av_sync_type == AV_SYNC_VIDEO_MASTER && play->m_video_st)
{
/* 暂无实现. */
}
/* 计算下一个audio的pts值. */
n = 2 * FFMIN(play->m_audio_ctx->channels, 2);

/* 防止内存过大. */
chk_queue(play, &play->m_audio_dq, AVDECODE_BUFFER_SIZE);
play->m_audio_clock += ((double) avcopy.linesize[0]
/ (double) (n * play->m_audio_ctx->sample_rate));

/* 丢到播放队列中. */
put_queue(&play->m_audio_dq, &avcopy);
/* 如果不是以音频同步为主, 则需要计算是否移除一些采样以同步到其它方式. */
if (play->m_av_sync_type == AV_SYNC_EXTERNAL_CLOCK ||
play->m_av_sync_type == AV_SYNC_VIDEO_MASTER && play->m_video_st)
{
/* 暂无实现. */
}

if (pkt2.size <= 0)
break;
}

/* 防止内存过大. */
chk_queue(play, &play->m_audio_dq, AVDECODE_BUFFER_SIZE);

/* 丢到播放队列中. */
put_queue(&play->m_audio_dq, &avcopy);
}
av_free_packet(&pkt);
}
}

if (audio_buf)
av_free(audio_buf);

av_free(audio_buf);
return NULL;
}

Expand Down Expand Up @@ -2366,3 +2368,8 @@ int logger(const char *fmt, ...)

return ret;
}

double buffering(avplay *play)
{
return play->m_buffering;
}
12 changes: 10 additions & 2 deletions libav/avplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ typedef struct avplay
/* 正在播放的索引, 只用于BT文件播放. */
int m_current_play_index;
double m_start_time;
double m_buffering;

/* 停止标志. */
int m_abort;
Expand Down Expand Up @@ -347,19 +348,26 @@ EXPORT_API void enable_calc_frame_rate(avplay *play);
EXPORT_API void enable_calc_bit_rate(avplay *play);

/*
* Get current real-time bit rate.
* Get current real-time bit rate.
* @param play pointer to the player.
* @This function return bit rate(kpbs).
*/
EXPORT_API int current_bit_rate(avplay *play);

/*
* Get current real-time frame rate.
* Get current real-time frame rate.
* @param play pointer to the player.
* @This function return frame rate(fps).
*/
EXPORT_API int current_frame_rate(avplay *play);

/*
* Get buffer progress.
* @param play pointer to the player.
* @This function return buffering(percent).
*/
EXPORT_API double buffering(avplay *play);

/*
* Blurring algorithm to the input video.
* @param frame pointer to the frame.
Expand Down

0 comments on commit d180bf1

Please sign in to comment.