/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * mpegplayer video thread implementation * * Copyright (c) 2007 Michael Sevakis * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "plugin.h" #include "mpegplayer.h" #include "mpeg2dec_config.h" #include "lib/grey.h" #include "video_out.h" #include "mpeg_settings.h" /** Video stream and thread **/ /* Video thread data passed around to its various functions */ struct video_thread_data { mpeg2dec_t *mpeg2dec; /* Our video decoder */ const mpeg2_info_t *info; /* Info about video stream */ int state; /* Thread state */ int status; /* Media status */ struct queue_event ev; /* Our event queue to receive commands */ int num_drawn; /* Number of frames drawn since reset */ int num_skipped; /* Number of frames skipped since reset */ uint32_t eta_stream; /* Current time of stream */ uint32_t eta_video; /* Time that frame has been scheduled for */ int32_t eta_early; /* How early has the frame been decoded? */ int32_t eta_late; /* How late has the frame been decoded? */ int frame_drop_level; /* Drop severity */ int skip_level; /* Skip severity */ long last_showfps; /* Last time the FPS display was updated */ long last_render; /* Last time a frame was drawn */ uint32_t curr_time; /* Current due time of frame */ uint32_t period; /* Frame period in clock ticks */ int syncf_perfect; /* Last sync fit result */ }; /* TODO: Check if 4KB is appropriate - it works for my test streams, so maybe we can reduce it. */ #define VIDEO_STACKSIZE (4*1024) static uint32_t video_stack[VIDEO_STACKSIZE / sizeof(uint32_t)] IBSS_ATTR; static struct event_queue video_str_queue SHAREDBSS_ATTR; static struct queue_sender_list video_str_queue_send SHAREDBSS_ATTR; struct stream video_str IBSS_ATTR; static void draw_fps(struct video_thread_data *td) { uint32_t start; uint32_t clock_ticks = stream_get_ticks(&start); int fps = 0; int buf_pct; char str[80]; clock_ticks -= start; if (clock_ticks != 0) fps = muldiv_uint32(CLOCK_RATE*100, td->num_drawn, clock_ticks); buf_pct = muldiv_uint32(100, pcm_output_used(), PCMOUT_BUFSIZE); rb->snprintf(str, sizeof(str), "v:%d.%02d %d %d a:%02d%% %d %d ", /* Video information */ fps / 100, fps % 100, td->num_skipped, td->info->display_picture->temporal_reference, /* Audio information */ buf_pct, pcm_underruns, pcm_skipped); lcd_(putsxy)(0, 0, str); vo_lock(); lcd_(update_rect)(0, 0, LCD_WIDTH, 8); vo_unlock(); td->last_showfps = *rb->current_tick; } #if defined(DEBUG) || defined(SIMULATOR) static unsigned char pic_coding_type_char(unsigned type) { switch (type) { case PIC_FLAG_CODING_TYPE_I: return 'I'; /* Intra-coded */ case PIC_FLAG_CODING_TYPE_P: return 'P'; /* Forward-predicted */ case PIC_FLAG_CODING_TYPE_B: return 'B'; /* Bidirectionally-predicted */ case PIC_FLAG_CODING_TYPE_D: return 'D'; /* DC-coded */ default: return '?'; /* Say what? */ } } #endif /* defined(DEBUG) || defined(SIMULATOR) */ /* Multi-use: * 1) Find the sequence header and initialize video out * 2) Find the end of the final frame */ static int video_str_scan(struct video_thread_data *td, struct str_sync_data *sd) { int retval = STREAM_ERROR; uint32_t time = INVALID_TIMESTAMP; uint32_t per# __________ __ ___. # Open \______ \ ____ ____ | | _\_ |__ _______ ___ # Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / # Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < # Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ # \/ \/ \/ \/ \/ # $Id$ # INCLUDES= -I$(FIRMDIR)/include -I$(FIRMDIR)/export -I. -I$(BUILDDIR) \ -I$(OBJDIR) CFLAGS = $(GCCOPTS) $(INCLUDES) $(TARGET) $(EXTRA_DEFINES) # This sets up 'SRC' based on the files mentioned in SOURCES include $(TOOLSDIR)/makesrc.inc SOURCES = $(SRC) CSRC := $(SRC:%.bmp=$(OBJDIR)/%.c) OBJS := $(CSRC:%.c=%.o) DEPFILE = $(OBJDIR)/dep-bitmaps-remotemono BMP2RB = $(BMP2RB_REMOTEMONO) OUTPUT = $(BUILDDIR)/libpluginbitmapsremotemono.a BMPINCDIR = $(BUILDDIR)/pluginbitmaps include $(TOOLSDIR)/makebmp.inc clean: $(call PRINTS,cleaning plugins/bitmaps/remotemono)rm -f $(CSRC) $(OBJS) $(OUTPUT) $(DEPFILE) @rmdir $(OBJDIR) -include $(DEPFILE)