This program plays QuickTime movies on GR-Peach
Dependencies: AsciiFont GR-PEACH_video GraphicsFramework LCD_shield_config R_BSP TLV320_RBSP mbed-rtos mbed
Requirements
- GR-Peach
- GR-Peach Audio Camera Shield or I²S compatible audio DAC
- GR-Peach LCD Shield
- USB memory stick
How to play movie files
- Encode movie files
encode movies with ffmpeg
$ ffmpeg -i <input -ar 44100 -acodec pcm_s16le -s 480x270 -vcodec mjpeg -q:v 3 -movflags faststart -threads 4 -vf fps=30 <output>.mov
- Copy movies to the root directory of USB memory
- Build and upload this program
- Run it
MovPlayer.cpp@1:3e638b9e91cd, 2017-03-12 (annotated)
- Committer:
- mtkrtk
- Date:
- Sun Mar 12 02:01:46 2017 +0000
- Revision:
- 1:3e638b9e91cd
- Parent:
- 0:d0f130e27d32
fixed lcd contrast pin
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mtkrtk | 0:d0f130e27d32 | 1 | #include "MovPlayer.hpp" |
mtkrtk | 0:d0f130e27d32 | 2 | |
mtkrtk | 0:d0f130e27d32 | 3 | MovPlayer::VideoBuffer MovPlayer::videoBuf[]; |
mtkrtk | 0:d0f130e27d32 | 4 | MovPlayer::AudioBuffer MovPlayer::audioBuf[]; |
mtkrtk | 0:d0f130e27d32 | 5 | unsigned char MovPlayer::audioThreadStack[]; |
mtkrtk | 0:d0f130e27d32 | 6 | MovPlayer MovPlayer::singleton; |
mtkrtk | 0:d0f130e27d32 | 7 | |
mtkrtk | 0:d0f130e27d32 | 8 | static void audioCallback(void MBED_UNUSED *p_data, int32_t result, void MBED_UNUSED *p_app_data) { |
mtkrtk | 0:d0f130e27d32 | 9 | if (result < 0) { |
mtkrtk | 0:d0f130e27d32 | 10 | printf("audio write callback error %ld\n", result); |
mtkrtk | 0:d0f130e27d32 | 11 | } |
mtkrtk | 0:d0f130e27d32 | 12 | // pc.printf("f"); |
mtkrtk | 0:d0f130e27d32 | 13 | } |
mtkrtk | 0:d0f130e27d32 | 14 | |
mtkrtk | 0:d0f130e27d32 | 15 | MovPlayer::MovPlayer() : audioThread(osPriorityNormal, DEFAULT_STACK_SIZE, audioThreadStack), frameTimer(mbed::Callback<void ()>(this, &MovPlayer::frameTimerCallback), osTimerPeriodic), frameSemaphore(0), mov(nullptr) |
mtkrtk | 0:d0f130e27d32 | 16 | { |
mtkrtk | 0:d0f130e27d32 | 17 | } |
mtkrtk | 0:d0f130e27d32 | 18 | |
mtkrtk | 0:d0f130e27d32 | 19 | void MovPlayer::frameTimerCallback() |
mtkrtk | 0:d0f130e27d32 | 20 | { |
mtkrtk | 0:d0f130e27d32 | 21 | frameSemaphore.release(); |
mtkrtk | 0:d0f130e27d32 | 22 | } |
mtkrtk | 0:d0f130e27d32 | 23 | |
mtkrtk | 0:d0f130e27d32 | 24 | void MovPlayer::audioProcessor() |
mtkrtk | 0:d0f130e27d32 | 25 | { |
mtkrtk | 0:d0f130e27d32 | 26 | VideoBuffer *videoP = videoBuf; |
mtkrtk | 0:d0f130e27d32 | 27 | AudioBuffer *audioP = audioBuf; |
mtkrtk | 0:d0f130e27d32 | 28 | rbsp_data_conf_t audioConf = {&audioCallback, NULL}; |
mtkrtk | 0:d0f130e27d32 | 29 | frameTimer.start(1e3 / 30 + 1); |
mtkrtk | 0:d0f130e27d32 | 30 | int index = BufferLength; |
mtkrtk | 0:d0f130e27d32 | 31 | while (1) { |
mtkrtk | 0:d0f130e27d32 | 32 | do { |
mtkrtk | 0:d0f130e27d32 | 33 | if (mov->read(videoP->buf, audioP->buf, &audioP->size)) { |
mtkrtk | 0:d0f130e27d32 | 34 | videoQueue.put(videoP); |
mtkrtk | 0:d0f130e27d32 | 35 | output(audioP->buf, audioP->size, &audioConf); |
mtkrtk | 0:d0f130e27d32 | 36 | ++videoP; |
mtkrtk | 0:d0f130e27d32 | 37 | ++audioP; |
mtkrtk | 0:d0f130e27d32 | 38 | } else { |
mtkrtk | 0:d0f130e27d32 | 39 | queueTimeout = 0; |
mtkrtk | 0:d0f130e27d32 | 40 | __ISB(); |
mtkrtk | 0:d0f130e27d32 | 41 | __DSB(); |
mtkrtk | 0:d0f130e27d32 | 42 | rtos::Thread::wait(osWaitForever); |
mtkrtk | 0:d0f130e27d32 | 43 | } |
mtkrtk | 0:d0f130e27d32 | 44 | } while (--index); |
mtkrtk | 0:d0f130e27d32 | 45 | videoP = videoBuf; |
mtkrtk | 0:d0f130e27d32 | 46 | audioP = audioBuf; |
mtkrtk | 0:d0f130e27d32 | 47 | index = BufferLength; |
mtkrtk | 0:d0f130e27d32 | 48 | } |
mtkrtk | 0:d0f130e27d32 | 49 | } |
mtkrtk | 0:d0f130e27d32 | 50 | |
mtkrtk | 0:d0f130e27d32 | 51 | void MovPlayer::play(MovFile *_mov, LCD *lcd, AudioCallback callback) |
mtkrtk | 0:d0f130e27d32 | 52 | { |
mtkrtk | 0:d0f130e27d32 | 53 | mov = _mov; |
mtkrtk | 0:d0f130e27d32 | 54 | output = callback; |
mtkrtk | 0:d0f130e27d32 | 55 | queueTimeout = osWaitForever; |
mtkrtk | 0:d0f130e27d32 | 56 | audioThread.start(mbed::Callback<void ()>(this, &MovPlayer::audioProcessor)); |
mtkrtk | 0:d0f130e27d32 | 57 | while (1) { |
mtkrtk | 0:d0f130e27d32 | 58 | osEvent event = videoQueue.get(queueTimeout); |
mtkrtk | 0:d0f130e27d32 | 59 | if (event.status == osEventMessage) { |
mtkrtk | 0:d0f130e27d32 | 60 | VideoBuffer *buf = reinterpret_cast<VideoBuffer *>(event.value.p); |
mtkrtk | 0:d0f130e27d32 | 61 | if (! (buf->buf[0] == 0xFF && buf->buf[1] == 0xD8)) { |
mtkrtk | 0:d0f130e27d32 | 62 | printf("m"); |
mtkrtk | 0:d0f130e27d32 | 63 | } |
mtkrtk | 0:d0f130e27d32 | 64 | frameSemaphore.wait(); |
mtkrtk | 0:d0f130e27d32 | 65 | lcd->drawImage(reinterpret_cast<graphics_image_t *>(buf->buf)); |
mtkrtk | 0:d0f130e27d32 | 66 | } else { |
mtkrtk | 0:d0f130e27d32 | 67 | audioThread.terminate(); |
mtkrtk | 0:d0f130e27d32 | 68 | frameTimer.stop(); |
mtkrtk | 0:d0f130e27d32 | 69 | while (frameSemaphore.wait(0) > 0) ; |
mtkrtk | 0:d0f130e27d32 | 70 | return; |
mtkrtk | 0:d0f130e27d32 | 71 | } |
mtkrtk | 0:d0f130e27d32 | 72 | } |
mtkrtk | 0:d0f130e27d32 | 73 | } |
mtkrtk | 0:d0f130e27d32 | 74 |