static void handle_pads(glw_ps3_t *gp) { PadInfo2 padinfo2; int i; if(gp->osk_widget) { clear_btns(); return; } // Check the pads. ioPadGetInfo2(&padinfo2); for(i=0; i<7; i++){ if(!padinfo2.port_status[i]) continue; if(padinfo2.device_type[i] == 4) { uint32_t type = 4; int r = ioPadGetDataExtra(i, &type, &paddata[i]); if(r == 0) { int btn = paddata[i].button[25]; if(btn != remote_last_btn[i]) { if(remote_last_btn[i] < 0xff) handle_btn(gp, i, bd_to_local_map[remote_last_btn[i]], 0, 0, 0); remote_last_btn[i] = btn; } if(btn != 0xff) handle_btn(gp, i, bd_to_local_map[btn], 1, 0, 0); } continue; } ioPadGetData(i, &paddata[i]); PadData *pd = &paddata[i]; int sel = !!pd->BTN_SELECT; handle_btn(gp, i, BTN_LEFT, pd->BTN_LEFT, sel, pd->PRE_LEFT); handle_btn(gp, i, BTN_UP, pd->BTN_UP, sel, pd->PRE_UP); handle_btn(gp, i, BTN_RIGHT, pd->BTN_RIGHT, sel, pd->PRE_RIGHT); handle_btn(gp, i, BTN_DOWN, pd->BTN_DOWN, sel, pd->PRE_DOWN); handle_btn(gp, i, BTN_CROSS, pd->BTN_CROSS, sel, pd->PRE_CROSS); handle_btn(gp, i, BTN_CIRCLE, pd->BTN_CIRCLE, sel, pd->PRE_CIRCLE); handle_btn(gp, i, BTN_TRIANGLE, pd->BTN_TRIANGLE, sel, pd->PRE_TRIANGLE); handle_btn(gp, i, BTN_SQUARE, pd->BTN_SQUARE, sel, pd->PRE_SQUARE); handle_btn(gp, i, BTN_START, pd->BTN_START, sel, 0); handle_btn(gp, i, BTN_R1, pd->BTN_R1, sel, pd->PRE_R1); handle_btn(gp, i, BTN_L1, pd->BTN_L1, sel, pd->PRE_L1); handle_btn(gp, i, BTN_R3, pd->BTN_R3, sel, 0); handle_btn(gp, i, BTN_L3, pd->BTN_L3, sel, 0); if(gp->gp_seekmode == 0 || (gp->gp_seekmode == 1 && sel)) { handle_seek(gp, i, 1, pd->BTN_R2, pd->PRE_R2); handle_seek(gp, i, -1, pd->BTN_L2, pd->PRE_L2); } } }
/* * System call handler * * retrieves system call number from user space * and invokes the requested method */ static void syscall_handler (struct intr_frame *f) { /* retrieve system call number and switch to corresponding method */ unsigned int syscall_number = *((unsigned int*) syscall_get_kernel_address(f->esp)); switch(syscall_number) { /* process system calls */ case SYS_HALT: handle_halt(f); break; case SYS_EXIT: handle_exit(f); break; case SYS_EXEC: handle_exec(f); break; case SYS_WAIT: handle_wait(f); break; /* file system calls */ case SYS_CREATE: handle_create(f); break; case SYS_REMOVE: handle_remove(f); break; case SYS_OPEN: handle_open(f); break; case SYS_FILESIZE: handle_filesize(f); break; case SYS_READ: handle_read(f); break; case SYS_WRITE: handle_write(f); break; case SYS_SEEK: handle_seek(f); break; case SYS_TELL: handle_tell(f); break; case SYS_CLOSE: handle_close(f); break; case SYS_CHDIR: handle_chdir(f); break; case SYS_MKDIR: handle_mkdir(f); break; case SYS_READDIR: handle_readdir(f); break; case SYS_ISDIR: handle_isdir(f); break; case SYS_INUMBER: handle_inumber(f); break; default: /* SYSCALL_ERROR: */ handle_no_such_syscall(f); break; } }
/** * MP3音乐播放回调函数,ME版本 * 负责将解码数据填充声音缓存区 * * @note 声音缓存区的格式为双声道,16位低字序 * * @param buf 声音缓冲区指针 * @param reqn 缓冲区帧大小 * @param pdata 用户数据,无用 */ static int memp3_audiocallback(void *buf, unsigned int reqn, void *pdata) { int avail_frame; int snd_buf_frame_size = (int) reqn; signed short *audio_buf = buf; double incr; uint16_t *output; UNUSED(pdata); if (g_status != ST_PLAYING) { if (handle_seek() == -1) { __end(); return -1; } xAudioClearSndBuf(buf, snd_buf_frame_size); xrKernelDelayThread(100000); return 0; } while (snd_buf_frame_size > 0) { avail_frame = g_buff_frame_size - g_buff_frame_start; if (avail_frame >= snd_buf_frame_size) { send_to_sndbuf(audio_buf, &g_buff[g_buff_frame_start * 2], snd_buf_frame_size, 2); g_buff_frame_start += snd_buf_frame_size; audio_buf += snd_buf_frame_size * 2; snd_buf_frame_size = 0; } else { int frame_size, ret, brate = 0; send_to_sndbuf(audio_buf, &g_buff[g_buff_frame_start * 2], avail_frame, 2); snd_buf_frame_size -= avail_frame; audio_buf += avail_frame * 2; do { if (mp3_data.use_buffer) { if ((frame_size = search_valid_frame_me_buffered(&mp3_data, &brate)) < 0) { __end(); return -1; } } else { if ((frame_size = search_valid_frame_me(&mp3_data, &brate)) < 0) { __end(); return -1; } } if (mp3_data.use_buffer) ret = buffered_reader_read(mp3_data.r, memp3_input_buf, frame_size); else ret = xrIoRead(mp3_data.fd, memp3_input_buf, frame_size); if (ret < 0) { __end(); return -1; } ret = memp3_decode(memp3_input_buf, ret, memp3_decoded_buf); } while (ret < 0); output = &g_buff[0]; memcpy(output, memp3_decoded_buf, mp3info.spf * 4); g_buff_frame_size = mp3info.spf; g_buff_frame_start = 0; incr = (double) mp3info.spf / mp3info.sample_freq; g_play_time += incr; add_bitrate(&g_inst_br, brate * 1000, incr); } } return 0; }
/** * MP3音乐播放回调函数, * 负责将解码数据填充声音缓存区 * * @note 声音缓存区的格式为双声道,16位低字序 * * @param buf 声音缓冲区指针 * @param reqn 缓冲区帧大小 * @param pdata 用户数据,无用 */ static int mp3_audiocallback(void *buf, unsigned int reqn, void *pdata) { int avail_frame; int snd_buf_frame_size = (int) reqn; int ret; double incr; signed short *audio_buf = buf; unsigned i; uint16_t *output; UNUSED(pdata); if (g_status != ST_PLAYING) { if (handle_seek() == -1) { __end(); return -1; } xAudioClearSndBuf(buf, snd_buf_frame_size); xrKernelDelayThread(100000); return 0; } while (snd_buf_frame_size > 0) { avail_frame = g_buff_frame_size - g_buff_frame_start; if (avail_frame >= snd_buf_frame_size) { send_to_sndbuf(audio_buf, &g_buff[g_buff_frame_start * 2], snd_buf_frame_size, 2); g_buff_frame_start += snd_buf_frame_size; audio_buf += snd_buf_frame_size * 2; snd_buf_frame_size = 0; } else { send_to_sndbuf(audio_buf, &g_buff[g_buff_frame_start * 2], avail_frame, 2); snd_buf_frame_size -= avail_frame; audio_buf += avail_frame * 2; if (stream.buffer == NULL || stream.error == MAD_ERROR_BUFLEN) { size_t read_size, remaining = 0; uint8_t *read_start; int bufsize; if (stream.next_frame != NULL) { remaining = stream.bufend - stream.next_frame; memmove(g_input_buff, stream.next_frame, remaining); read_start = g_input_buff + remaining; read_size = BUFF_SIZE - remaining; } else { read_size = BUFF_SIZE; read_start = g_input_buff; remaining = 0; } if (mp3_data.use_buffer) bufsize = buffered_reader_read(mp3_data.r, read_start, read_size); else bufsize = xrIoRead(mp3_data.fd, read_start, read_size); if (bufsize <= 0) { __end(); return -1; } if (bufsize < read_size) { uint8_t *guard = read_start + read_size; memset(guard, 0, MAD_BUFFER_GUARD); read_size += MAD_BUFFER_GUARD; } mad_stream_buffer(&stream, g_input_buff, read_size + remaining); stream.error = 0; } ret = mad_frame_decode(&frame, &stream); if (ret == -1) { if (MAD_RECOVERABLE(stream.error) || stream.error == MAD_ERROR_BUFLEN) { if (stream.error == MAD_ERROR_LOSTSYNC) { long tagsize = id3_tag_query(stream.this_frame, stream.bufend - stream.this_frame); if (tagsize > 0) { mad_stream_skip(&stream, tagsize); } if (mad_header_decode(&frame.header, &stream) == -1) { if (stream.error != MAD_ERROR_BUFLEN) { if (!MAD_RECOVERABLE(stream.error)) { __end(); return -1; } } } else { stream.error = MAD_ERROR_NONE; } } g_buff_frame_size = 0; g_buff_frame_start = 0; continue; } else { __end(); return -1; } } output = &g_buff[0]; if (stream.error != MAD_ERROR_NONE) { continue; } mad_synth_frame(&synth, &frame); for (i = 0; i < synth.pcm.length; i++) { signed short sample; if (MAD_NCHANNELS(&frame.header) == 2) { /* Left channel */ sample = MadFixedToSshort(synth.pcm.samples[0][i]); *(output++) = sample; sample = MadFixedToSshort(synth.pcm.samples[1][i]); *(output++) = sample; } else { sample = MadFixedToSshort(synth.pcm.samples[0][i]); *(output++) = sample; *(output++) = sample; } } g_buff_frame_size = synth.pcm.length; g_buff_frame_start = 0; incr = frame.header.duration.seconds; incr += mad_timer_fraction(frame.header.duration, MAD_UNITS_MILLISECONDS) / 1000.0; g_play_time += incr; add_bitrate(&g_inst_br, frame.header.bitrate, incr); } } return 0; }
static void *demux_thread(void *opaque) { struct ff_demuxer *demuxer = (struct ff_demuxer *) opaque; int result; struct ff_packet packet = {0}; if (!open_input(demuxer, &demuxer->format_context)) goto fail; av_dump_format(demuxer->format_context, 0, demuxer->input, 0); if (!find_and_initialize_stream_decoders(demuxer)) goto fail; ff_demuxer_reset(demuxer); while (!demuxer->abort) { // failed to seek (looping?) if (!handle_seek(demuxer)) break; if (ff_decoder_full(demuxer->audio_decoder) || ff_decoder_full(demuxer->video_decoder)) { av_usleep(10 * 1000); // 10ms continue; } result = av_read_frame(demuxer->format_context, &packet.base); if (result < 0) { bool eof = false; if (result == AVERROR_EOF) { eof = true; } else if (demuxer->format_context->pb != NULL) { AVIOContext *io_context = demuxer->format_context->pb; if (io_context->error == 0) { av_usleep(100 * 1000); // 100ms continue; } else { if (io_context->eof_reached != 0) eof = true; } } if (eof) { if (demuxer->options.is_looping) { seek_beginning(demuxer); } else { break; } continue; } else { av_log(NULL, AV_LOG_ERROR, "av_read_frame() failed: %s", av_err2str(result)); break; } } if (ff_decoder_accept(demuxer->video_decoder, &packet)) continue; else if (ff_decoder_accept(demuxer->audio_decoder, &packet)) continue; else av_free_packet(&packet.base); } if (demuxer->audio_decoder != NULL) demuxer->audio_decoder->eof = true; if (demuxer->video_decoder != NULL) demuxer->video_decoder->eof = true; fail: demuxer->abort = true; return NULL; }