X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=ffplay.c;h=b7b2b0bd2377145cb39cad631baef595eab1eb3d;hb=9762554dd0e9116d28169f602380e7ccd2949ac5;hp=d302793924bcccddca8b196dac5e3439e79ca93c;hpb=73e9f04ea5e80e7b99420ec4bbf6995430146ff8;p=ffmpeg diff --git a/ffplay.c b/ffplay.c index d302793924b..b7b2b0bd237 100644 --- a/ffplay.c +++ b/ffplay.c @@ -73,6 +73,9 @@ const int program_birth_year = 2003; /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */ #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30 +/* Step size for volume control */ +#define SDL_VOLUME_STEP (SDL_MIX_MAXVOLUME / 50) + /* no AV sync correction is done if below the minimum AV sync threshold */ #define AV_SYNC_THRESHOLD_MIN 0.04 /* AV sync correction is done if above the maximum AV sync threshold */ @@ -246,6 +249,8 @@ typedef struct VideoState { unsigned int audio_buf1_size; int audio_buf_index; /* in bytes */ int audio_write_buf_size; + int audio_volume; + int muted; struct AudioParams audio_src; #if CONFIG_AVFILTER struct AudioParams audio_filter_src; @@ -285,7 +290,7 @@ typedef struct VideoState { SDL_Rect last_display_rect; int eof; - char filename[1024]; + char *filename; int width, height, xleft, ytop; int step; @@ -446,12 +451,21 @@ static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index) } /* packet queue handling */ -static void packet_queue_init(PacketQueue *q) +static int packet_queue_init(PacketQueue *q) { memset(q, 0, sizeof(PacketQueue)); q->mutex = SDL_CreateMutex(); + if (!q->mutex) { + av_log(q, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError()); + return AVERROR(ENOMEM); + } q->cond = SDL_CreateCond(); + if (!q->cond) { + av_log(q, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError()); + return AVERROR(ENOMEM); + } q->abort_request = 1; + return 0; } static void packet_queue_flush(PacketQueue *q) @@ -1132,6 +1146,7 @@ static void stream_close(VideoState *is) sws_freeContext(is->img_convert_ctx); #endif sws_freeContext(is->sub_convert_ctx); + av_free(is->filename); av_free(is); } @@ -1348,6 +1363,16 @@ static void toggle_pause(VideoState *is) is->step = 0; } +static void toggle_mute(VideoState *is) +{ + is->muted = !is->muted; +} + +static void update_volume(VideoState *is, int sign, int step) +{ + is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME); +} + static void step_to_next_frame(VideoState *is) { /* if the stream is paused unpause it, then step */ @@ -2447,7 +2472,13 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len) len1 = is->audio_buf_size - is->audio_buf_index; if (len1 > len) len1 = len; - memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1); + if (!is->muted && is->audio_volume == SDL_MIX_MAXVOLUME) + memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1); + else { + memset(stream, is->silence_buf[0], len1); + if (!is->muted) + SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume); + } len -= len1; stream += len1; is->audio_buf_index += len1; @@ -3099,7 +3130,9 @@ static VideoState *stream_open(const char *filename, AVInputFormat *iformat) is = av_mallocz(sizeof(VideoState)); if (!is) return NULL; - av_strlcpy(is->filename, filename, sizeof(is->filename)); + is->filename = av_strdup(filename); + if (!is->filename) + goto fail; is->iformat = iformat; is->ytop = 0; is->xleft = 0; @@ -3112,9 +3145,10 @@ static VideoState *stream_open(const char *filename, AVInputFormat *iformat) if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0) goto fail; - packet_queue_init(&is->videoq); - packet_queue_init(&is->audioq); - packet_queue_init(&is->subtitleq); + if (packet_queue_init(&is->videoq) < 0 || + packet_queue_init(&is->audioq) < 0 || + packet_queue_init(&is->subtitleq) < 0) + goto fail; is->continue_read_thread = SDL_CreateCond(); @@ -3122,6 +3156,8 @@ static VideoState *stream_open(const char *filename, AVInputFormat *iformat) init_clock(&is->audclk, &is->audioq.serial); init_clock(&is->extclk, &is->extclk.serial); is->audio_clock_serial = -1; + is->audio_volume = SDL_MIX_MAXVOLUME; + is->muted = 0; is->av_sync_type = av_sync_type; is->read_tid = SDL_CreateThread(read_thread, is); if (!is->read_tid) { @@ -3311,6 +3347,17 @@ static void event_loop(VideoState *cur_stream) case SDLK_SPACE: toggle_pause(cur_stream); break; + case SDLK_m: + toggle_mute(cur_stream); + break; + case SDLK_KP_MULTIPLY: + case SDLK_0: + update_volume(cur_stream, 1, SDL_VOLUME_STEP); + break; + case SDLK_KP_DIVIDE: + case SDLK_9: + update_volume(cur_stream, -1, SDL_VOLUME_STEP); + break; case SDLK_s: // S: Step to next frame step_to_next_frame(cur_stream); break; @@ -3644,6 +3691,9 @@ void show_help_default(const char *opt, const char *arg) "q, ESC quit\n" "f toggle full screen\n" "p, SPC pause\n" + "m toggle mute\n" + "9, 0 decrease and increase volume respectively\n" + "/, * decrease and increase volume respectively\n" "a cycle audio channel in the current program\n" "v cycle video channel\n" "t cycle subtitle channel in the current program\n" @@ -3740,6 +3790,8 @@ int main(int argc, char **argv) SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE); SDL_EventState(SDL_USEREVENT, SDL_IGNORE); + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); + if (av_lockmgr_register(lockmgr)) { av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n"); do_exit(NULL);