A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 201 lines 8.1 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Declarations for stream-specific threading 11 * 12 * Copyright (c) 2007 Michael Sevakis 13 * 14 * This program is free software; you can redistribute it and/or 15 * modify it under the terms of the GNU General Public License 16 * as published by the Free Software Foundation; either version 2 17 * of the License, or (at your option) any later version. 18 * 19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 20 * KIND, either express or implied. 21 * 22 ****************************************************************************/ 23#ifndef STREAM_THREAD_H 24#define STREAM_THREAD_H 25 26#define PKT_HAS_TS 0x1 27 28/* Stream header which is the minimum to receive asynchronous buffering 29 * notifications. 30 * Layed-out to allow streaming access after random-access parsing */ 31struct stream_hdr 32{ 33 struct event_queue *q; /* Communication queue - separate to allow it 34 to be placed in another section */ 35 off_t win_left; /* Left position within data stream */ 36 union 37 { 38 off_t win_right; /* Right position within data stream */ 39 off_t pos; /* Start/current position for random-access read */ 40 }; 41 off_t limit; /* Limit for random-access read */ 42}; 43 44struct stream 45{ 46 struct stream_hdr hdr; /* Base stream data */ 47 unsigned int thread; /* Stream's thread */ 48 uint8_t* curr_packet; /* Current stream packet beginning */ 49 uint8_t* curr_packet_end; /* Current stream packet end */ 50 int state; /* State machine parsing mode */ 51 uint32_t start_pts; /* First timestamp for stream */ 52 uint32_t end_pts; /* Last timestamp for stream */ 53 uint32_t pts; /* Last presentation timestamp */ 54 uint32_t pkt_flags; /* PKT_* flags */ 55 unsigned id; /* Stream identifier */ 56}; 57 58#define STR_FROM_HDR(sh) ((struct stream *)(sh)) 59 60/* Make sure there there is always enough data buffered ahead for 61 * the worst possible case - regardless of whether a valid stream 62 * would actually produce that */ 63#define MIN_BUFAHEAD (21+65535+6+65535+6) /* 131103 */ 64 65/* States that a stream's thread assumes internally */ 66enum thread_states 67{ 68 /* Stream thread... */ 69 TSTATE_INIT = 0, /* is initialized and primed */ 70 TSTATE_DATA, /* is awaiting data to be available */ 71 TSTATE_BUFFERING, /* is buffering data */ 72 TSTATE_EOS, /* has hit the end of data */ 73 TSTATE_DECODE, /* is in a decoding state */ 74 TSTATE_RENDER, /* is in a rendering state */ 75 TSTATE_RENDER_WAIT, /* is waiting to render */ 76}; 77 78/* Commands that streams respond to */ 79enum stream_message 80{ 81 STREAM_NULL = 0, /* A NULL message for whatever reason - 82 usually ignored */ 83 STREAM_PLAY, /* Start playback at current position */ 84 STREAM_PAUSE, /* Stop playing and await further commands */ 85 STREAM_RESET, /* Reset the stream for a discontinuity */ 86 STREAM_STOP, /* Stop stream - requires a reset later */ 87 STREAM_SEEK, /* Seek the current stream to a new location */ 88 STREAM_OPEN, /* Open a new file */ 89 STREAM_CLOSE, /* Close the current file */ 90 STREAM_QUIT, /* Exit the stream and thread */ 91 STREAM_NEEDS_SYNC, /* Need to sync before stream decoding? */ 92 STREAM_SYNC, /* Sync to the specified time from some key point */ 93 STREAM_FIND_END_TIME, /* Get the exact end time of an elementary 94 * stream - ie. time just after last frame is finished */ 95 /* Disk buffer */ 96 STREAM_DISK_BUF_FIRST, 97 DISK_BUF_DATA_NOTIFY = STREAM_DISK_BUF_FIRST, 98 DISK_BUF_CLEAR_DATA_NOTIFY, /* Cancel pending data notification */ 99 DISK_BUF_CACHE_RANGE, /* Cache a range of the file in the buffer */ 100 /* Audio stream */ 101 STREAM_AUDIO_FIRST, 102 /* Video stream */ 103 STREAM_VIDEO_FIRST, 104 VIDEO_DISPLAY_SHOW = STREAM_VIDEO_FIRST, /* Show/hide video output */ 105 VIDEO_DISPLAY_IS_VISIBLE, /* Is the video output visible? */ 106 VIDEO_GET_SIZE, /* Get the video dimensions */ 107 VIDEO_PRINT_FRAME, /* Print the frame at the current position */ 108 VIDEO_PRINT_THUMBNAIL, /* Print a thumbnail of the current position */ 109 VIDEO_SET_CLIP_RECT, /* Set the visible video area */ 110 VIDEO_GET_CLIP_RECT, /* Return the visible video area */ 111 VIDEO_SET_POST_FRAME_CALLBACK, /* Set a callback after frame is drawn */ 112 STREAM_MESSAGE_LAST, 113}; 114 115/* Data parameter for STREAM_SEEK */ 116struct stream_seek_data 117{ 118 uint32_t time; /* Time to seek to/by */ 119 int whence; /* Specification of relationship to current position/file */ 120}; 121 122/* Data parameter for STREAM_SYNC */ 123struct str_sync_data 124{ 125 uint32_t time; /* Time to sync to */ 126 struct stream_scan sk; /* Specification of start/limits/direction */ 127}; 128 129/* Stream status codes - not eqivalent to thread states */ 130enum stream_status 131{ 132 /* Stream status is... */ 133 STREAM_DATA_END = -4, /* Stream has ended */ 134 STREAM_DATA_NOT_READY = -3, /* Data was not available yet */ 135 STREAM_UNSUPPORTED = -2, /* Format is unsupported */ 136 STREAM_ERROR = -1, /* some kind of error - quit it or reset it */ 137 STREAM_OK = 0, /* General inequality for success >= is OK, < error */ 138 STREAM_STOPPED = 0, /* stopped and awaiting commands - send STREAM_INIT */ 139 STREAM_PLAYING, /* playing and rendering its data */ 140 STREAM_PAUSED, /* paused and awaiting commands */ 141 /* Other status codes (> STREAM_OK) */ 142 STREAM_MATCH, /* A good match was found */ 143 STREAM_PERFECT_MATCH, /* Exactly what was wanted was found or 144 no better match is possible */ 145 STREAM_NOT_FOUND, /* Match not found */ 146}; 147 148/* Clip time to range for a particular stream */ 149static inline uint32_t clip_time(struct stream *str, uint32_t time) 150{ 151 if (time < str->start_pts) 152 time = str->start_pts; 153 else if (time >= str->end_pts) 154 time = str->end_pts; 155 156 return time; 157} 158 159extern struct stream video_str IBSS_ATTR; 160extern struct stream audio_str IBSS_ATTR; 161 162bool video_thread_init(void); 163void video_thread_exit(void); 164 165struct video_output_stats 166{ 167 int num_drawn; /* Number of frames drawn since reset */ 168 int num_skipped; /* Number of frames skipped since reset */ 169 int fps; /* fps rate in 100ths of a frame per second */ 170}; 171 172void video_thread_get_stats(struct video_output_stats *s); 173 174bool audio_thread_init(void); 175void audio_thread_exit(void); 176 177 178/* Some queue function wrappers to keep things clean-ish */ 179 180/* For stream use only */ 181static inline bool str_have_msg(struct stream *str) 182 { return !rb->queue_empty(str->hdr.q); } 183 184static inline void str_get_msg(struct stream *str, struct queue_event *ev) 185 { rb->queue_wait(str->hdr.q, ev); } 186 187static inline void str_get_msg_w_tmo(struct stream *str, struct queue_event *ev, 188 int timeout) 189 { rb->queue_wait_w_tmo(str->hdr.q, ev, timeout); } 190 191static inline void str_reply_msg(struct stream *str, intptr_t reply) 192 { rb->queue_reply(str->hdr.q, reply); } 193 194/* Public use */ 195static inline intptr_t str_send_msg(struct stream *str, long id, intptr_t data) 196 { return rb->queue_send(str->hdr.q, id, data); } 197 198static inline void str_post_msg(struct stream *str, long id, intptr_t data) 199 { rb->queue_post(str->hdr.q, id, data); } 200 201#endif /* STREAM_THREAD_H */