From 4b978f23107dafccf2406bb73e7da71cca363a11 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Fri, 5 Feb 2016 19:36:09 +0000 Subject: [PATCH] Fplay: new init_decoder()/fini_decoder() git-svn-id: svn://kolibrios.org@6144 a494cfbc-eb01-0410-851d-a64ba20cac60 --- contrib/media/fplay/Makefile | 2 +- contrib/media/fplay/audio.c | 18 +-- contrib/media/fplay/decoder.c | 232 +++++++++++++++++++++++++++ contrib/media/fplay/fplay.c | 60 ++----- contrib/media/fplay/fplay.h | 36 +++-- contrib/media/fplay/vaapi.c | 164 +++++++++---------- contrib/media/fplay/video.c | 125 ++------------- contrib/media/fplay/winlib/button.c | 1 + contrib/media/fplay/winlib/caption.c | 2 + contrib/media/fplay/winlib/control.h | 1 + contrib/media/fplay/winlib/window.c | 1 + 11 files changed, 375 insertions(+), 267 deletions(-) create mode 100644 contrib/media/fplay/decoder.c diff --git a/contrib/media/fplay/Makefile b/contrib/media/fplay/Makefile index 50fabe6263..08a391a342 100644 --- a/contrib/media/fplay/Makefile +++ b/contrib/media/fplay/Makefile @@ -1,4 +1,3 @@ - NAME= Fplay FASM= fasm.exe @@ -27,6 +26,7 @@ LDFLAGS = -static -nostdlib --stack 0x200000 -Map fplay.map -T$(SDK_DIR)/sources SOURCES = opendial.asm \ audio.c \ + decoder.c \ fplay.c \ vaapi.c \ video.c \ diff --git a/contrib/media/fplay/audio.c b/contrib/media/fplay/audio.c index 34119993ef..02ea46d6df 100644 --- a/contrib/media/fplay/audio.c +++ b/contrib/media/fplay/audio.c @@ -29,9 +29,6 @@ static int snd_format; int sample_rate; static uint32_t samples_written = 0; -double audio_base = -1.0; - -double get_audio_base(); int init_audio(int format) { @@ -128,14 +125,6 @@ int decode_audio(AVCodecContext *ctx, queue_t *qa) int data_size = av_samples_get_buffer_size(&plane_size, ctx->channels, aFrame->nb_samples, ctx->sample_fmt, 1); - -// if(audio_base == -1.0) -// { -// if (pkt.pts != AV_NOPTS_VALUE) -// audio_base = get_audio_base() * pkt.pts; -// printf("audio base %f\n", audio_base); -// }; - pkt_tmp.data += len; pkt_tmp.size -= len; @@ -254,6 +243,7 @@ static void sync_audio(SNDBUF hbuff, int buffsize) int audio_thread(void *param) { + vst_t *vst = param; SND_EVENT evnt; int buffsize; @@ -306,11 +296,10 @@ int audio_thread(void *param) memcpy(astream.buffer, astream.buffer+buffsize*2, astream.count); mutex_unlock(&astream.lock); - SetTimeBase(hBuff, audio_base); + SetTimeBase(hBuff, vst->audio_timer_base); case PAUSE_2_PLAY: GetTimeStamp(hBuff, &last_time_stamp); -// printf("last audio time stamp %f\n", last_time_stamp); if((err = PlayBuffer(hBuff, 0)) !=0 ) { @@ -320,7 +309,6 @@ int audio_thread(void *param) active = 1; sync_audio(hBuff, buffsize); sound_state = PLAY; -// printf("render: set audio latency to %f\n", audio_delta); /* breaktrough */ @@ -385,7 +373,7 @@ int audio_thread(void *param) if( active ) { ResetBuffer(hBuff, SND_RESET_ALL); - audio_base = -1.0; + vst->audio_timer_valid = 0; active = 0; } sound_state = STOP; diff --git a/contrib/media/fplay/decoder.c b/contrib/media/fplay/decoder.c new file mode 100644 index 0000000000..15e80b6900 --- /dev/null +++ b/contrib/media/fplay/decoder.c @@ -0,0 +1,232 @@ +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include "winlib/winlib.h" + +#include "sound.h" +#include "fplay.h" + +static struct decoder* init_ffmpeg_decoder(vst_t *vst) +{ + AVCodecContext *vCtx = vst->vCtx; + struct decoder *decoder; + vframe_t *vframe; + int i, ret; + + decoder = calloc(1, sizeof(struct decoder)); + if(decoder == NULL) + return NULL; + + decoder->Frame = av_frame_alloc(); + if(decoder->Frame == NULL) + goto err_0; + + decoder->nframes = 4; + + for(i = 0; i < decoder->nframes; i++) + { + vframe = &decoder->vframes[i]; + + ret = avpicture_alloc(&vframe->picture, vCtx->pix_fmt, + vCtx->width, vCtx->height); + if ( ret != 0 ) + goto err_1; + + vframe->format = vCtx->pix_fmt; + vframe->index = i; + vframe->pts = 0; + vframe->ready = 0; + list_add_tail(&vframe->list, &vst->input_list); + }; + + if(avcodec_open2(vCtx, vst->vCodec, NULL) < 0) + { + printf("Error while opening codec for input stream %d\n", + vst->vStream); + goto err_1; + }; + + decoder->name = vst->vCodec->name; + decoder->pix_fmt = vCtx->pix_fmt; + decoder->width = vCtx->width; + decoder->height = vCtx->height; + decoder->codec_id = vCtx->codec_id; + + return decoder; + +err_1: + for(i = i-1; i >= 0; i--) + { + vframe = &decoder->vframes[i]; + avpicture_free(&vframe->picture); + }; + av_frame_free(&decoder->Frame); +err_0: + free(decoder); + return NULL; +} + +int init_video_decoder(vst_t *vst) +{ + AVCodecContext *vCtx = vst->vCtx; + + vst->vCodec = avcodec_find_decoder(vCtx->codec_id); + + if(vst->vCodec == NULL) + { + printf("Unsupported codec with id %d for input stream %d\n", + vst->vCtx->codec_id, vst->vStream); + return -1; + } + + vst->decoder = va_init_decoder(vst); + if(vst->decoder == NULL) + vst->decoder = init_ffmpeg_decoder(vst); + + if(vst->decoder != NULL) + { + printf("%dx%d %s %s%s decoder\n", + vst->decoder->width, vst->decoder->height, + av_get_pix_fmt_name(vst->decoder->pix_fmt), + vst->decoder->is_hw == 0 ? "ffmpeg ":"vaapi ", + vst->decoder->name); + + return 0; + }; + + return -1; +} + +void fini_video_decoder(vst_t *vst) +{ + avcodec_close(vst->vCtx); + + if(vst->decoder->is_hw != 0) + return; + + for(int i = 0; i < vst->decoder->nframes; i++) + { + vframe_t *vframe; + vframe = &vst->decoder->vframes[i]; + avpicture_free(&vframe->picture); + }; + av_frame_free(&vst->decoder->Frame); + free(vst->decoder); +}; + +static vframe_t *get_input_frame(vst_t *vst) +{ + vframe_t *vframe = NULL; + + mutex_lock(&vst->input_lock); + if(!list_empty(&vst->input_list)) + { + vframe = list_first_entry(&vst->input_list, vframe_t, list); + list_del(&vframe->list); + } + mutex_unlock(&vst->input_lock); + + return vframe; +} + +static void put_output_frame(vst_t *vst, vframe_t *vframe) +{ + mutex_lock(&vst->output_lock); + if(list_empty(&vst->output_list)) + list_add_tail(&vframe->list, &vst->output_list); + else + { + vframe_t *cur; + + cur = list_first_entry(&vst->output_list,vframe_t,list); + if(vframe->pts < cur->pts) + list_add_tail(&vframe->list, &vst->output_list); + else + { + list_for_each_entry_reverse(cur,&vst->output_list,list) + { + if(vframe->pts > cur->pts) + { + list_add(&vframe->list, &cur->list); + break; + }; + }; + }; + }; + vst->frames_count++; + mutex_unlock(&vst->output_lock); +}; + +int decode_video(vst_t* vst) +{ + struct decoder* decoder = vst->decoder; + double pts; + AVPacket pkt; + + int frameFinished; + + if(decoder->active_frame == NULL) + decoder->active_frame = get_input_frame(vst); + + if(decoder->active_frame == NULL) + return -1; + + if( get_packet(&vst->q_video, &pkt) == 0 ) + return 0; + + frameFinished = 0; + + mutex_lock(&vst->gpu_lock); + + if(avcodec_decode_video2(vst->vCtx, decoder->Frame, &frameFinished, &pkt) <= 0) + printf("video decoder error\n"); + + if(frameFinished) + { + vframe_t *vframe = decoder->active_frame; + AVPicture *dst_pic; + + if(decoder->is_hw) + pts = pkt.pts; + else + pts = av_frame_get_best_effort_timestamp(decoder->Frame); + + pts*= av_q2d(vst->video_time_base); + + dst_pic = &vframe->picture; + + if(vframe->is_hw_pic == 0) + av_image_copy(dst_pic->data, dst_pic->linesize, + (const uint8_t**)decoder->Frame->data, + decoder->Frame->linesize, vst->vCtx->pix_fmt, vst->vCtx->width, vst->vCtx->height); + else + va_create_planar(vst, vframe); + + vframe->pts = pts*1000.0; + vframe->pkt_pts = pkt.pts*av_q2d(vst->video_time_base)*1000.0; + vframe->ready = 1; + + put_output_frame(vst, vframe); + +// printf("decoded index: %d pts: %f pkt_pts %f pkt_dts %f\n", +// vst->dfx, vst->vframe[vst->dfx].pts, +// vst->vframe[vst->dfx].pkt_pts, vst->vframe[vst->dfx].pkt_dts); + + decoder->active_frame = NULL; + }; + av_frame_unref(decoder->Frame); + mutex_unlock(&vst->gpu_lock); + + av_free_packet(&pkt); + + return 1; +} + diff --git a/contrib/media/fplay/fplay.c b/contrib/media/fplay/fplay.c index 813991249b..4d0c256a62 100644 --- a/contrib/media/fplay/fplay.c +++ b/contrib/media/fplay/fplay.c @@ -22,8 +22,6 @@ volatile enum player_state sound_state = STOP; uint32_t win_width, win_height; -int have_sound = 0; - uint8_t *decoder_buffer; extern int resampler_size; extern int sample_rate; @@ -34,8 +32,6 @@ int64_t stream_duration; int threads_running = DECODER_THREAD; -extern double audio_base; - int main( int argc, char *argv[]) { @@ -70,7 +66,6 @@ int main( int argc, char *argv[]) vst.fCtx->flags |= AVFMT_FLAG_GENPTS; - // Retrieve stream information if(avformat_find_stream_info(vst.fCtx, NULL) < 0) { printf("Cannot find streams\n\r"); @@ -89,7 +84,6 @@ int main( int argc, char *argv[]) stream_duration = vst.fCtx->duration; - // Find the first video stream vst.vStream = -1; vst.aStream = -1; @@ -108,7 +102,6 @@ int main( int argc, char *argv[]) vst.aStream < 0) { vst.aStream = i; - vst.audio_time_base = vst.fCtx->streams[i]->time_base; if(stream_duration == 0) stream_duration = vst.fCtx->streams[i]->duration; } @@ -122,12 +115,6 @@ int main( int argc, char *argv[]) // __asm__ __volatile__("int3"); - // Get a pointer to the codec context for the video stream - vst.vCtx = vst.fCtx->streams[vst.vStream]->codec; - vst.aCtx = vst.fCtx->streams[vst.aStream]->codec; - - vst.vCodec = avcodec_find_decoder(vst.vCtx->codec_id); - INIT_LIST_HEAD(&vst.input_list); INIT_LIST_HEAD(&vst.output_list); mutex_init(&vst.q_video.lock); @@ -137,37 +124,14 @@ int main( int argc, char *argv[]) mutex_init(&vst.input_lock); mutex_init(&vst.output_lock); - if(vst.vCodec == NULL) - { - printf("Unsupported codec with id %d for input stream %d\n", - vst.vCtx->codec_id, vst.vStream); - return -1; - } + vst.vCtx = vst.fCtx->streams[vst.vStream]->codec; + vst.aCtx = vst.fCtx->streams[vst.aStream]->codec; - vst.Frame = av_frame_alloc(); - if(vst.Frame == NULL) - { - printf("Cannot alloc video frame\n"); - return -1; - }; - - if(fplay_init_context(&vst)) + if(init_video_decoder(&vst) != 0 ) return -1; - if(avcodec_open2(vst.vCtx, vst.vCodec, NULL) < 0) - { - printf("Error while opening codec for input stream %d\n", - vst.vStream); - return -1; // Could not open codec - }; - - if (vst.aCtx->channels > 0) - vst.aCtx->request_channels = FFMIN(2, vst.aCtx->channels); - else - vst.aCtx->request_channels = 2; - + vst.aCtx->request_channel_layout = AV_CH_LAYOUT_STEREO; vst.aCodec = avcodec_find_decoder(vst.aCtx->codec_id); - if(vst.aCodec) { if(avcodec_open2(vst.aCtx, vst.aCodec, NULL) >= 0 ) @@ -198,11 +162,11 @@ int main( int argc, char *argv[]) astream.count = 0; astream.buffer = (char *)av_mallocz(192000*3); if( astream.buffer != NULL ) - have_sound = 1; + vst.has_sound = 1; else av_free(decoder_buffer); } - if( have_sound == 0) + if( vst.has_sound == 0) { printf("Not enough memory for audio buffers\n"); } @@ -229,9 +193,11 @@ int main( int argc, char *argv[]) if(astream.lock.handle) mutex_destroy(&astream.lock); + fini_video_decoder(&vst); mutex_destroy(&vst.q_video.lock); mutex_destroy(&vst.q_audio.lock); mutex_destroy(&vst.decoder_lock); + return 0; } @@ -247,14 +213,14 @@ static int load_frame(vst_t *vst) if(packet.stream_index == vst->vStream) put_packet(&vst->q_video, &packet); else if( (packet.stream_index == vst->aStream) && - (have_sound != 0) ) + (vst->has_sound != 0) ) { put_packet(&vst->q_audio, &packet); - if(audio_base == -1.0) + if(vst->audio_timer_valid == 0 && + packet.pts != AV_NOPTS_VALUE ) { - if (packet.pts != AV_NOPTS_VALUE) - audio_base = get_audio_base(vst) * packet.pts; -// printf("audio base %f\n", audio_base); + vst->audio_timer_base = get_audio_base(vst) * packet.pts; + vst->audio_timer_valid = 1; }; } else av_free_packet(&packet); diff --git a/contrib/media/fplay/fplay.h b/contrib/media/fplay/fplay.h index 40e2455f41..95c18e4a39 100644 --- a/contrib/media/fplay/fplay.h +++ b/contrib/media/fplay/fplay.h @@ -110,6 +110,22 @@ typedef struct { int put_packet(queue_t *q, AVPacket *pkt); int get_packet(queue_t *q, AVPacket *pkt); +struct decoder +{ + const char *name; + enum AVCodecID codec_id; + enum AVPixelFormat pix_fmt; + int width; + int height; + AVFrame *Frame; + vframe_t *active_frame; + void *hwctx; + int is_hw:1; + int frame_reorder:1; + int nframes; + vframe_t vframes[16]; +}; + struct vstate { AVFormatContext *fCtx; /* format context */ @@ -122,7 +138,7 @@ struct vstate int vStream; /* video stream index */ int aStream; /* audio stream index */ AVRational video_time_base; - AVRational audio_time_base; + double audio_timer_base; queue_t q_video; /* video packets queue */ queue_t q_audio; /* audio packets queue */ @@ -135,18 +151,13 @@ struct vstate struct list_head input_list; struct list_head output_list; - AVFrame *Frame; - - vframe_t *decoder_frame; + struct decoder *decoder; volatile int frames_count; - void *hwCtx; /* hardware context */ - int hwdec:1; /* hardware decoder */ + int has_sound:1; + int audio_timer_valid:1; int blit_bitmap:1; /* hardware RGBA blitter */ int blit_texture:1; /* hardware RGBA blit and scale */ int blit_planar:1; /* hardbare YUV blit and scale */ - int frame_reorder:1; - int nframes; - vframe_t vframes[16]; }; @@ -173,6 +184,8 @@ void set_audio_volume(int left, int right); int video_thread(void *param); void flush_video(vst_t* vst); +int init_video_decoder(vst_t *vst); +void fini_video_decoder(vst_t *vst); void decoder(vst_t *vst); int decode_video(vst_t* vst); int decode_audio(AVCodecContext *ctx, queue_t *qa); @@ -191,8 +204,13 @@ static inline double get_audio_base(vst_t* vst) return (double)av_q2d(vst->fCtx->streams[vst->aStream]->time_base)*1000; }; +struct decoder* va_init_decoder(vst_t *vst); void va_create_planar(vst_t *vst, vframe_t *vframe); int init_fontlib(); char *get_moviefile(); +#define ENTER() printf("enter %s\n",__FUNCTION__) +#define LEAVE() printf("leave %s\n",__FUNCTION__) +#define FAIL() printf("fail %s\n",__FUNCTION__) + diff --git a/contrib/media/fplay/vaapi.c b/contrib/media/fplay/vaapi.c index 7b3287f8f8..fa702d09ef 100644 --- a/contrib/media/fplay/vaapi.c +++ b/contrib/media/fplay/vaapi.c @@ -160,21 +160,6 @@ static const char *string_of_VAEntrypoint(VAEntrypoint entrypoint) return ""; } -VADisplay va_open_display(void) -{ - VADisplay va_dpy; - - drm_fd = get_service("DISPLAY"); - if (drm_fd == 0) - return NULL; - - va_dpy = vaGetDisplayDRM(drm_fd); - if (va_dpy) - return va_dpy; - - drm_fd = 0; - return NULL; -}; void *vaapi_init(VADisplay display) { @@ -343,7 +328,7 @@ ENTER(); printf("vaCreateSurfaces %dx%d\n",picture_width,picture_height); status = vaCreateSurfaces(vaapi->display, VA_RT_FORMAT_YUV420, picture_width, picture_height, - v_surface_id,vst->nframes,NULL,0); + v_surface_id,vst->decoder->nframes,NULL,0); if (!vaapi_check_status(status, "vaCreateSurfaces()")) { FAIL(); @@ -378,7 +363,7 @@ ENTER(); status = vaCreateContext(vaapi->display, config_id, picture_width, picture_height, VA_PROGRESSIVE, - v_surface_id, vst->nframes, + v_surface_id, vst->decoder->nframes, &context_id); if (!vaapi_check_status(status, "vaCreateContext()")) { @@ -399,7 +384,7 @@ static enum PixelFormat get_format(struct AVCodecContext *avctx, vst_t *vst = (vst_t*)avctx->opaque; VAProfile profile = VAProfileNone; - +ENTER(); for (int i = 0; fmt[i] != PIX_FMT_NONE; i++) { enum AVCodecID codec = avctx->codec_id; @@ -449,7 +434,7 @@ static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags) vst_t *vst = (vst_t*)avctx->opaque; void *surface; - surface = (void *)(uintptr_t)v_surface_id[vst->decoder_frame->index]; + surface = (void *)(uintptr_t)v_surface_id[vst->decoder->active_frame->index]; pic->data[3] = surface; @@ -466,71 +451,6 @@ static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags) struct vaapi_context va_context_storage; -int fplay_init_context(vst_t *vst) -{ - AVCodecContext *vCtx = vst->vCtx; - - vst->nframes = 4; - - if(va_check_codec_support(vCtx->codec_id)) - { - VADisplay dpy; - - dpy = va_open_display(); - vst->hwCtx = vaapi_init(dpy); - - if(vst->hwCtx != NULL) - { - if(vCtx->codec_id == AV_CODEC_ID_H264) - vst->nframes = 16; - - for(int i = 0; i < vst->nframes; i++) - { - vframe_t *vframe = &vst->vframes[i]; - - vframe->format = AV_PIX_FMT_NONE; - vframe->is_hw_pic = 1; - vframe->index = i; - vframe->pts = 0; - vframe->ready = 0; - list_add_tail(&vframe->list, &vst->input_list); - }; - - vst->hwdec = 1; - vst->frame_reorder = 1; - vCtx->opaque = vst; - vCtx->thread_count = 1; - vCtx->get_format = get_format; - vCtx->get_buffer2 = get_buffer2; - return 0; - }; - }; - - vst->hwdec = 0; - - for(int i = 0; i < vst->nframes; i++) - { - vframe_t *vframe; - int ret; - - vframe = &vst->vframes[i]; - - ret = avpicture_alloc(&vframe->picture, vst->vCtx->pix_fmt, - vst->vCtx->width, vst->vCtx->height); - if ( ret != 0 ) - { - printf("Cannot alloc video buffer\n\r"); - return ret; - }; - vframe->format = vst->vCtx->pix_fmt; - vframe->index = i; - vframe->pts = 0; - vframe->ready = 0; - list_add_tail(&vframe->list, &vst->input_list); - }; - - return 0; -} #define EGL_TEXTURE_Y_U_V_WL 0x31D7 @@ -648,7 +568,6 @@ void va_create_planar(vst_t *vst, vframe_t *vframe) vaimage.offsets[2],vaimage.pitches[2]); if(planar != NULL) { - printf("create planar image\n",planar); vframe->planar = planar; vframe->format = AV_PIX_FMT_NV12; }; @@ -657,3 +576,78 @@ void va_create_planar(vst_t *vst, vframe_t *vframe) vaDestroyImage(vaapi->display, vaimage.image_id); } + +struct decoder* va_init_decoder(vst_t *vst) +{ + AVCodecContext *vCtx = vst->vCtx; + struct decoder *decoder; + VADisplay dpy; + + drm_fd = get_service("DISPLAY"); + if (drm_fd == 0) + return NULL; + + dpy = vaGetDisplayDRM(drm_fd); + if (dpy == NULL) + goto err_0; + + decoder = calloc(1, sizeof(struct decoder)); + if(decoder == NULL) + goto err_0; + + decoder->hwctx = vaapi_init(dpy); + if(decoder->hwctx == NULL) + goto err_1; + + decoder->Frame = av_frame_alloc(); + if(decoder->Frame == NULL) + goto err_1; + + if(vCtx->codec_id == AV_CODEC_ID_H264) + decoder->nframes = 16; + else + decoder->nframes = 4; + + for(int i = 0; i < decoder->nframes; i++) + { + vframe_t *vframe = &decoder->vframes[i]; + + vframe->format = AV_PIX_FMT_NONE; + vframe->is_hw_pic = 1; + vframe->index = i; + vframe->pts = 0; + vframe->ready = 0; + list_add_tail(&vframe->list, &vst->input_list); + }; + + vCtx->opaque = vst; + vCtx->thread_count = 1; + vCtx->get_format = get_format; + vCtx->get_buffer2 = get_buffer2; + + if(avcodec_open2(vst->vCtx, vst->vCodec, NULL) < 0) + { + printf("Error while opening codec for input stream %d\n", + vst->vStream); + goto err_2; + }; + + decoder->name = vst->vCodec->name; + decoder->codec_id = vCtx->codec_id; + decoder->pix_fmt = vCtx->pix_fmt; + decoder->width = vCtx->width; + decoder->height = vCtx->height; + decoder->is_hw = 1; + decoder->frame_reorder = 1; + + return decoder; + +err_2: + av_frame_free(&decoder->Frame); +err_1: + free(decoder); + vaTerminate(dpy); +err_0: + drm_fd = 0; + return NULL; +} diff --git a/contrib/media/fplay/video.c b/contrib/media/fplay/video.c index 5978bd7987..45043fcf0b 100644 --- a/contrib/media/fplay/video.c +++ b/contrib/media/fplay/video.c @@ -40,7 +40,7 @@ void flush_video(vst_t *vst) list_for_each_entry_safe(vframe, tmp, &vst->output_list, list) list_move_tail(&vframe->list, &vst->input_list); - list_for_each_entry(vframe, &vst->output_list, list) + list_for_each_entry(vframe, &vst->input_list, list) { vframe->pts = 0; vframe->ready = 0; @@ -52,112 +52,6 @@ void flush_video(vst_t *vst) }; -static vframe_t *get_input_frame(vst_t *vst) -{ - vframe_t *vframe = NULL; - - mutex_lock(&vst->input_lock); - if(!list_empty(&vst->input_list)) - { - vframe = list_first_entry(&vst->input_list, vframe_t, list); - list_del(&vframe->list); - } - mutex_unlock(&vst->input_lock); - - return vframe; -} - -static void put_output_frame(vst_t *vst, vframe_t *vframe) -{ - mutex_lock(&vst->output_lock); - if(list_empty(&vst->output_list)) - list_add_tail(&vframe->list, &vst->output_list); - else - { - vframe_t *cur; - - cur = list_first_entry(&vst->output_list,vframe_t,list); - if(vframe->pts < cur->pts) - list_add_tail(&vframe->list, &vst->output_list); - else - { - list_for_each_entry_reverse(cur,&vst->output_list,list) - { - if(vframe->pts > cur->pts) - { - list_add(&vframe->list, &cur->list); - break; - }; - }; - }; - }; - vst->frames_count++; - mutex_unlock(&vst->output_lock); -}; - -int decode_video(vst_t* vst) -{ - double pts; - AVPacket pkt; - - int frameFinished; - - if(vst->decoder_frame == NULL) - vst->decoder_frame = get_input_frame(vst); - - if(vst->decoder_frame == NULL) - return -1; - - if( get_packet(&vst->q_video, &pkt) == 0 ) - return 0; - - frameFinished = 0; - - mutex_lock(&vst->gpu_lock); - - if(avcodec_decode_video2(vst->vCtx, vst->Frame, &frameFinished, &pkt) <= 0) - printf("video decoder error\n"); - - if(frameFinished) - { - vframe_t *vframe = vst->decoder_frame;; - AVPicture *dst_pic; - - if(vst->hwdec) - pts = pkt.pts; - else - pts = av_frame_get_best_effort_timestamp(vst->Frame); - - pts*= av_q2d(vst->video_time_base); - - dst_pic = &vframe->picture; - - if(vframe->is_hw_pic == 0) - av_image_copy(dst_pic->data, dst_pic->linesize, - (const uint8_t**)vst->Frame->data, - vst->Frame->linesize, vst->vCtx->pix_fmt, vst->vCtx->width, vst->vCtx->height); - else - va_create_planar(vst, vframe); - - vframe->pts = pts*1000.0; - vframe->pkt_pts = pkt.pts*av_q2d(vst->video_time_base)*1000.0; - vframe->ready = 1; - - put_output_frame(vst, vframe); - -// printf("decoded index: %d pts: %f pkt_pts %f pkt_dts %f\n", -// vst->dfx, vst->vframe[vst->dfx].pts, -// vst->vframe[vst->dfx].pkt_pts, vst->vframe[vst->dfx].pkt_dts); - - vst->decoder_frame = NULL; - }; - av_frame_unref(vst->Frame); - mutex_unlock(&vst->gpu_lock); - - av_free_packet(&pkt); - - return 1; -} extern volatile enum player_state player_state; extern volatile enum player_state decoder_state; @@ -482,6 +376,18 @@ int video_thread(void *param) __sync_and_and_fetch(&threads_running,~VIDEO_THREAD); + { + vframe_t *vframe, *tmp; + flush_video(vst); + + list_for_each_entry_safe(vframe, tmp, &vst->output_list, list) + { + list_del(&vframe->list); + if(vframe->planar != NULL) + pxDestroyPlanar(vframe->planar); + } + } + destroy_render(main_render); fini_winlib(); player_state = CLOSED; @@ -737,7 +643,6 @@ static void render_hw_planar(render_t *render, vframe_t *vframe) CAPTION_HEIGHT+render->rcvideo.t, render->rcvideo.r, render->rcvideo.b,0,0); mutex_unlock(&render->vst->gpu_lock); - } }; @@ -770,7 +675,7 @@ void draw_hw_picture(render_t *render, vframe_t *vframe) dst_height = render->rcvideo.b; }; - if(vst->hwdec) + if(vframe->is_hw_pic) { render_hw_planar(render, vframe); return; @@ -778,7 +683,7 @@ void draw_hw_picture(render_t *render, vframe_t *vframe) picture = &vframe->picture; - format = render->vst->hwdec == 0 ? render->ctx_format : AV_PIX_FMT_BGRA; + format = render->ctx_format; cvt_ctx = sws_getCachedContext(cvt_ctx, render->ctx_width, render->ctx_height, format, dst_width, dst_height, AV_PIX_FMT_BGRA, SWS_FAST_BILINEAR, NULL, NULL, NULL); diff --git a/contrib/media/fplay/winlib/button.c b/contrib/media/fplay/winlib/button.c index f1cf7d48e9..5063fe3ed7 100644 --- a/contrib/media/fplay/winlib/button.c +++ b/contrib/media/fplay/winlib/button.c @@ -16,6 +16,7 @@ uint32_t main_cursor; static int button_proc(ctrl_t *btn, uint32_t msg, uint32_t arg1, uint32_t arg2); static int spinbtn_proc(ctrl_t *btn, uint32_t msg, uint32_t arg1, uint32_t arg2); +void panel_set_layout(ctrl_t *panel, int layout); ctrl_t *create_control(size_t size, int id, int x, int y, int w, int h, ctrl_t *parent) diff --git a/contrib/media/fplay/winlib/caption.c b/contrib/media/fplay/winlib/caption.c index 9385975661..5f3804a107 100644 --- a/contrib/media/fplay/winlib/caption.c +++ b/contrib/media/fplay/winlib/caption.c @@ -25,6 +25,8 @@ extern int res_full_btn_pressed[]; extern uint32_t main_cursor; void update_caption_size(window_t *win); +void window_update_layout(window_t *win); +int draw_text_ext(void *pixmap, uint32_t pitch, int face, char *text, rect_t *rc, int color); int caption_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2); diff --git a/contrib/media/fplay/winlib/control.h b/contrib/media/fplay/winlib/control.h index f0b92cc96a..5ead38083f 100644 --- a/contrib/media/fplay/winlib/control.h +++ b/contrib/media/fplay/winlib/control.h @@ -203,6 +203,7 @@ static inline int pt_in_rect(rect_t *rc, int x, int y) ctrl_t *get_child(ctrl_t *ctrl, int x, int y); ctrl_t *capture_mouse(ctrl_t *newm); +void release_mouse(void); void blit_raw(ctx_t *ctx, void *raw, int x, int y, int w, int h, int pitch); diff --git a/contrib/media/fplay/winlib/window.c b/contrib/media/fplay/winlib/window.c index 6dac48523c..bd7e21a7bf 100644 --- a/contrib/media/fplay/winlib/window.c +++ b/contrib/media/fplay/winlib/window.c @@ -38,6 +38,7 @@ void adjust_frame(window_t *win); void blit_panel(panel_t *panel); void update_panel_size(window_t *win); void update_caption_size(window_t *win); +int init_fontlib(); //#include "timer.h" ctrl_t *win_get_child(window_t *win, int x, int y)