📄 mp4_play.c.svn-base
字号:
}static int is_video_keyframe(volatile struct mp4_play_struct *p, int video_frame) { int i; mp4info_track_t* track = p->decoder.reader.file.info->tracks[p->decoder.reader.file.video_track_id]; for(i = 0; i < track->stss_entry_count; i++ ) { if ( video_frame+1 == track->stss_sync_sample[i] ) return 1; } return 0; }static int mp4_next_audio_frame(volatile struct mp4_play_struct *p, int current_video_frame) { uint64_t timestamp = current_video_frame; timestamp *= p->decoder.video_frame_duration; timestamp /= p->decoder.audio_frame_duration; return (int)timestamp;}static void mp4_next_frame(volatile struct mp4_play_struct *p, int* current_video_frame, int* current_audio_frame, int video_step, int audio_step) { // save last keyframe pos if (is_video_keyframe(p, *current_video_frame)) p->last_keyframe_pos = *current_video_frame; if (p->resume_pos>0) { int pos = p->resume_pos; p->resume_pos = 0; *current_video_frame = pos; *current_audio_frame = mp4_next_audio_frame(p, pos); return; } if (p->seek > 0) { int number_of_skips = 0; if (p->seek == 2) { number_of_skips = 20; } int new_video_frame = *current_video_frame + 1; while (new_video_frame < p->decoder.reader.file.number_of_video_frames) { if (is_video_keyframe(p, new_video_frame)) { if (number_of_skips == 0) { break;//return(new_video_frame); } else { number_of_skips--; } } new_video_frame++; } if ( new_video_frame > p->decoder.reader.file.number_of_video_frames ) { *current_video_frame = p->decoder.reader.file.number_of_video_frames; } else { *current_video_frame = new_video_frame; } *current_audio_frame = mp4_next_audio_frame(p, *current_video_frame); return; } if (p->seek < 0) { int number_of_skips = 0; if (p->seek == -2) { number_of_skips = 20; } int new_video_frame = *current_video_frame - 1; while (new_video_frame > 0) { if (is_video_keyframe(p, new_video_frame)) { if (number_of_skips == 0) { break;//return(new_video_frame); } else { number_of_skips--; } } new_video_frame--; } if ( new_video_frame < 0 ) { *current_video_frame = 0; } else { *current_video_frame = new_video_frame; } *current_audio_frame = mp4_next_audio_frame(p, *current_video_frame); //seek back, skip all decoded frame in cahce int i; for(i = 0; i < p->decoder.number_of_frame_buffers; i++) p->decoder.output_video_frame_buffers[i].timestamp = -p->decoder.video_frame_duration; return; } *current_video_frame = *current_video_frame + video_step; *current_audio_frame = *current_audio_frame + audio_step; return;}char *mp4_play_start(volatile struct mp4_play_struct *p) { sceKernelStartThread(p->output_thread, 4, &p); sceKernelStartThread(p->show_thread, 4, &p); int current_video_frame = 0; int current_audio_frame = 0; int next_video_frame = 0; int next_read_video_frame = 0; int cached_video_frame = 0; sceCtrlSetSamplingCycle(0); sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); SceCtrlData previous_controller; sceCtrlPeekBufferPositive(&previous_controller, 1); while (p->return_request == 0 && current_video_frame != p->decoder.reader.file.number_of_video_frames) { mp4_input(p, &previous_controller); int wait; char* result; int video_step = 0; int audio_step = 0; wait = mp4_wait(p, p->semaphore_can_put_audio, "mp4_play_start: sceKernelWaitSema failed on semaphore_can_put_audio"); if ( wait == -1) { break; } else if ( wait == 1) { result = mp4_decode_get_audio((struct mp4_decode_struct *) &p->decoder, current_audio_frame, p->audio_stream, p->audio_channel, 1, p->volume_boost); audio_step++; if (result != 0) { p->return_result = result; p->return_request = 1; break; } if (sceKernelSignalSema(p->semaphore_can_get_audio, 1) < 0) { p->return_result = "mp4_play_start: sceKernelSignalSema failed on semaphore_can_get_audio"; p->return_request = 1; break; } } wait = mp4_wait(p, p->semaphore_can_put_video, "mp4_play_start: sceKernelWaitSema failed on semaphore_can_put_video"); if ( wait == -1) { break; } else if ( wait == 1) { if ( current_video_frame != next_video_frame ) { next_read_video_frame = current_video_frame; cached_video_frame = 0; } if ( cached_video_frame > 0 ) { result = mp4_decode_get_cached_video((struct mp4_decode_struct *) &p->decoder, cached_video_frame, current_video_frame, p->audio_stream, p->volume_boost, p->aspect_ratio, p->zoom, p->luminosity_boost, p->show_interface, p->subtitle, p->subtitle_format, p->loop); if (result != 0) { p->return_result = result; p->return_request = 1; break; } cached_video_frame--; next_video_frame = current_video_frame+1; video_step++; if (sceKernelSignalSema(p->semaphore_can_get_video, 1) < 0) { p->return_result = "mp4_play_start: sceKernelSignalSema failed on semaphore_can_get_video"; p->return_request = 1; break; } } else { result = mp4_decode_get_video((struct mp4_decode_struct *) &p->decoder, next_read_video_frame, current_video_frame, p->audio_stream, p->volume_boost, p->aspect_ratio, p->zoom, p->luminosity_boost, p->show_interface, p->subtitle, p->subtitle_format, p->loop, &cached_video_frame); if (result != 0) { p->return_result = result; p->return_request = 1; break; } next_read_video_frame++; if ( cached_video_frame >= 0 ) { next_video_frame = current_video_frame+1; video_step++; if (sceKernelSignalSema(p->semaphore_can_get_video, 1) < 0) { p->return_result = "mp4_play_start: sceKernelSignalSema failed on semaphore_can_get_video"; p->return_request = 1; break; } } else { next_video_frame = current_video_frame; if (sceKernelSignalSema(p->semaphore_can_put_video, 1) < 0) { p->return_result = "mp4_play_start: sceKernelSignalSema failed on semaphore_can_put_video1"; p->return_request = 1; break; } } } } // wait = mp4_wait(p, p->semaphore_can_put_audio, "mp4_play_start: sceKernelWaitSema failed on semaphore_can_put_audio");// if ( wait == -1) {// break;// }// else if ( wait == 1) {// result = mp4_decode_get_audio((struct mp4_decode_struct *) &p->decoder, current_audio_frame, p->audio_stream, p->audio_channel, 1, p->volume_boost);// audio_step++;// if (result != 0) {// p->return_result = result;// p->return_request = 1;// break;// }//// if (sceKernelSignalSema(p->semaphore_can_get_audio, 1) < 0) {// p->return_result = "mp4_play_start: sceKernelSignalSema failed on semaphore_can_get_audio";// p->return_request = 1;// break;// }// } mp4_next_frame(p, ¤t_video_frame, ¤t_audio_frame, video_step, audio_step); if ((p->loop == 1) && (current_video_frame == p->decoder.reader.file.number_of_video_frames)) { current_video_frame = 0; current_audio_frame = 0; } sceKernelDelayThread(10); } if (current_video_frame == p->decoder.reader.file.number_of_video_frames) { p->last_keyframe_pos = 0; } sceKernelDelayThread(1000000); p->return_request = 1; sceKernelWaitThreadEnd(p->output_thread, 0); sceKernelWaitThreadEnd(p->show_thread, 0); return(p->return_result);}char *mp4_play_open(struct mp4_play_struct *p, struct movie_file_struct *movie, int usePos, int pspType, int tvAspectRatio, int tvWidth, int tvHeight, int videoMode) { mp4_play_safe_constructor(p); p->subtitle = 0; p->subtitle_count = 0; char *result = mp4_decode_open(&p->decoder, movie->movie_file, pspType, tvAspectRatio, tvWidth, tvHeight, videoMode); if (result != 0) { mp4_play_close(p, 0, pspType); return(result); } if (subtitle_parse_search( movie, p->decoder.reader.file.video_rate, p->decoder.reader.file.video_scale, &p->subtitle_count)==0) p->subtitle = 1; if ( cooleyesAudioSetFrequency(sceKernelDevkitVersion(), p->decoder.reader.file.audio_rate) != 0) { mp4_play_close(p, 0, pspType); return("mp4_play_open: sceAudioSetFrequency failed"); } p->audio_reserved = sceAudioChReserve(0, p->decoder.reader.file.audio_resample_scale, PSP_AUDIO_FORMAT_STEREO); if (p->audio_reserved < 0) { mp4_play_close(p, 0, pspType); return("mp4_play_open: sceAudioChReserve failed"); } p->semaphore_can_get_video = sceKernelCreateSema("can_get_video", 0, 0, p->decoder.number_of_frame_buffers, 0); if (p->semaphore_can_get_video < 0) { mp4_play_close(p, 0, pspType); return("mp4_play_open: sceKernelCreateSema failed on semaphore_can_get_video"); } p->semaphore_can_put_video = sceKernelCreateSema("can_put_video", 0, p->decoder.number_of_frame_buffers, p->decoder.number_of_frame_buffers, 0); if (p->semaphore_can_put_video < 0) { mp4_play_close(p, 0, pspType); return("mp4_play_open: sceKernelCreateSema failed on semaphore_can_put_video"); } p->semaphore_can_get_audio = sceKernelCreateSema("can_get_audio", 0, 0, p->decoder.number_of_frame_buffers, 0); if (p->semaphore_can_get_audio < 0) { mp4_play_close(p, 0, pspType); return("mp4_play_open: sceKernelCreateSema failed on semaphore_can_get_audio"); } p->semaphore_can_put_audio = sceKernelCreateSema("can_put_audio", 0, p->decoder.number_of_frame_buffers, p->decoder.number_of_frame_buffers, 0); if (p->semaphore_can_put_audio < 0) { mp4_play_close(p, 0, pspType); return("mp4_play_open: sceKernelCreateSema failed on semaphore_can_put_audio"); } //p->output_thread = sceKernelCreateThread("output", mp4_output_thread, 0x8, 0x10000, 0, 0); p->output_thread = sceKernelCreateThread("output", mp4_output_thread, 0x3D, 0x10000, PSP_THREAD_ATTR_USER, 0); if (p->output_thread < 0) { mp4_play_close(p, 0, pspType); return("mp4_play_open: sceKernelCreateThread failed on output_thread"); } //p->show_thread = sceKernelCreateThread("show", mp4_show_thread, 0x8, 0x10000, 0, 0); p->show_thread = sceKernelCreateThread("show", mp4_show_thread, 0x3F, 0x10000, PSP_THREAD_ATTR_USER, 0); if (p->show_thread < 0) { mp4_play_close(p, 0, pspType); return("mp4_play_open: sceKernelCreateThread failed on show_thread"); } p->return_request = 0; p->return_result = 0; p->paused = 0; p->seek = 0; p->audio_stream = 0; p->audio_channel = 0; p->volume_boost = 3; p->aspect_ratio = 0; p->zoom = 100; p->luminosity_boost = 0; p->show_interface = 0; p->loop = 0; p->resume_pos = 0; p->last_keyframe_pos= 0; p->subtitle_format = (((gufont_haveflags&GU_FONT_HAS_UNICODE_CHARMAP))?1:0); p->subtitle_fontcolor = 0; p->subtitle_bordercolor = 0; memcpy(p->hash, movie->movie_hash, 16); if (usePos) mp4_stat_load( p ); return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -