diff options
author | Tuomas Virtanen <katajakasa@gmail.com> | 2016-01-21 00:34:11 +0200 |
---|---|---|
committer | Tuomas Virtanen <katajakasa@gmail.com> | 2016-01-21 00:34:11 +0200 |
commit | 3f8e07f2f3f972d0ba1f09f4e77605678047d59c (patch) | |
tree | 1afe3ab0b6668ad1b6a8c6ed244cda7d5fc541b3 /src/kitplayer.c | |
parent | e22d99c342f4eacf46de0ad2158d98ac1f588380 (diff) |
Make sure to read ALL audio and video data from avpackets
Diffstat (limited to 'src/kitplayer.c')
-rw-r--r-- | src/kitplayer.c | 98 |
1 files changed, 54 insertions, 44 deletions
diff --git a/src/kitplayer.c b/src/kitplayer.c index e9bfad4..3209cc0 100644 --- a/src/kitplayer.c +++ b/src/kitplayer.c @@ -338,55 +338,62 @@ static void _HandleVideoPacket(Kit_Player *player, AVPacket *packet) { AVFormatContext *fmt_ctx = (AVFormatContext *)player->src->format_ctx; AVPicture *iframe = (AVPicture*)player->tmp_vframe; - avcodec_decode_video2(vcodec_ctx, (AVFrame*)player->tmp_vframe, &frame_finished, packet); - - if(frame_finished) { - // Target frame - AVPicture *oframe = av_malloc(sizeof(AVPicture)); - avpicture_alloc( - oframe, - _FindAVPixelFormat(player->vformat.format), - vcodec_ctx->width, - vcodec_ctx->height); - - // Scale from source format to target format, don't touch the size - sws_scale( - (struct SwsContext *)player->sws, - (const unsigned char * const *)iframe->data, - iframe->linesize, - 0, - vcodec_ctx->height, - oframe->data, - oframe->linesize); - - // Get pts - double pts = 0; - if(packet->dts != AV_NOPTS_VALUE) { - pts = av_frame_get_best_effort_timestamp(player->tmp_vframe); - pts *= av_q2d(fmt_ctx->streams[player->src->vstream_idx]->time_base); + while(packet->size > 0) { + int len = avcodec_decode_video2(vcodec_ctx, (AVFrame*)player->tmp_vframe, &frame_finished, packet); + if(len < 0) { + return; } - // Just seeked, set sync clock & pos. - if(player->seek_flag == 1) { - player->vclock_pos = pts; - player->clock_sync = _GetSystemTime() - pts; - player->seek_flag = 0; - } + if(frame_finished) { + // Target frame + AVPicture *oframe = av_malloc(sizeof(AVPicture)); + avpicture_alloc( + oframe, + _FindAVPixelFormat(player->vformat.format), + vcodec_ctx->width, + vcodec_ctx->height); + + // Scale from source format to target format, don't touch the size + sws_scale( + (struct SwsContext *)player->sws, + (const unsigned char * const *)iframe->data, + iframe->linesize, + 0, + vcodec_ctx->height, + oframe->data, + oframe->linesize); - // Lock, write to audio buffer, unlock - Kit_VideoPacket *vpacket = _CreateVideoPacket(oframe, pts); - bool done = false; - if(SDL_LockMutex(player->vmutex) == 0) { - if(Kit_WriteBuffer((Kit_Buffer*)player->vbuffer, vpacket) == 0) { - done = true; + // Get pts + double pts = 0; + if(packet->dts != AV_NOPTS_VALUE) { + pts = av_frame_get_best_effort_timestamp(player->tmp_vframe); + pts *= av_q2d(fmt_ctx->streams[player->src->vstream_idx]->time_base); } - SDL_UnlockMutex(player->vmutex); - } - // Unable to write packet, free it. - if(!done) { - _FreeVideoPacket(vpacket); + // Just seeked, set sync clock & pos. + if(player->seek_flag == 1) { + player->vclock_pos = pts; + player->clock_sync = _GetSystemTime() - pts; + player->seek_flag = 0; + } + + // Lock, write to audio buffer, unlock + Kit_VideoPacket *vpacket = _CreateVideoPacket(oframe, pts); + bool done = false; + if(SDL_LockMutex(player->vmutex) == 0) { + if(Kit_WriteBuffer((Kit_Buffer*)player->vbuffer, vpacket) == 0) { + done = true; + } + SDL_UnlockMutex(player->vmutex); + } + + // Unable to write packet, free it. + if(!done) { + _FreeVideoPacket(vpacket); + } } + packet->size -= len; + packet->data += len; } } @@ -404,7 +411,7 @@ static void _HandleAudioPacket(Kit_Player *player, AVPacket *packet) { struct SwrContext *swr = (struct SwrContext *)player->swr; AVFrame *aframe = (AVFrame*)player->tmp_aframe; - if(packet->size > 0) { + while(packet->size > 0) { len = avcodec_decode_audio4(acodec_ctx, aframe, &frame_finished, packet); if(len < 0) { return; @@ -470,6 +477,9 @@ static void _HandleAudioPacket(Kit_Player *player, AVPacket *packet) { av_freep(&dst_data[0]); av_freep(&dst_data); } + + packet->size -= len; + packet->data += len; } } |