日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ffplay.c学习-8-暂停、逐帧、⾳量

發布時間:2024/4/11 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ffplay.c学习-8-暂停、逐帧、⾳量 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ffplay.c學習-8-暫停、逐幀、?量


目錄

  • 播放、暫停
  • 暫停/繼續狀態切換
  • 暫停狀態下的視頻播放
  • 暫停狀態下的?頻播放
  • 逐幀、調?量、靜?
  • 逐幀
  • 調?量
  • 靜?

  • 常?的播放器操作:
  • 播放:程序啟動即播放,處于暫停時通過p或空格鍵
  • 靜?:m鍵
  • ?量+:0鍵
  • ?量-:9鍵
  • 暫停:p或空格鍵
  • 快退/快進:左箭頭/右箭頭
  • 逐幀:s鍵
  • 退出:q或Esc鍵
  • 全屏:f或者?標左鍵雙擊
  • event_loop做按鍵響應
  • 1. 播放、暫停

  • 畫?要停?
  • 畫?停留在最后?幀
  • 聲?要停?
  • ?頻回調接?請求數據幀時直接填0
  • 讀取數據是否要停??
  • ?視頻包緩存隊列滿時進?休眠。
  • 暫停->繼續 :時鐘的恢復
  • 暫停:toggle_pause()
  • 1. 暫停/繼續狀態切換

  • 函數調?關系如下
  • main() --> event_loop() --> toggle_pause() --> stream_toggle_pause()
  • stream_toggle_pause()實現狀態翻轉:
  • /* pause or resume the video */ static void stream_toggle_pause(VideoState *is) {// 如果當前是暫停 -> 恢復播放// 正常播放 -> 暫停if (is->paused) {// 當前是暫停,那這個時候進來這個函數就是要恢復播放/* 恢復暫停狀態時也需要恢復時鐘,需要更新vidclk */// 加上 暫停->恢復 經過的時間is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;if (is->read_pause_return != AVERROR(ENOSYS)) {is->vidclk.paused = 0;}// 設置時鐘的意義,暫停狀態下讀取的是單純pts// 重新矯正video時鐘set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);}set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);// 切換 pause/resume 兩種狀態is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;printf("is->step = %d; stream_toggle_pause\n", is->step); }

    2. 暫停狀態下的視頻播放

  • 在video_refresh()函數中有如下代碼:
  • /* called to display each frame */static void video_refresh(void *opaque, double *remaining_time){......//視頻播放if (is->video_st) {......// 暫停處理:不停播放上?幀圖像if (is->paused)goto display;......}......}
  • 在暫停狀態下,實際就是不停播放上?幀(最后?幀)圖像。畫?不更新.
  • 3. 暫停狀態下的?頻播放

  • sdl_audio_callback -> audio_decode_frame
  • static int audio_decode_frame(VideoState *is){int data_size, resampled_data_size;int64_t dec_channel_layout;av_unused double audio_clock0;int wanted_nb_samples;Frame *af;(is->paused)return -1; // 暫停返回-1, 但這?返回-1并不會導致程序結束。....}

    2. 逐幀、調?量、靜?

    1. 逐幀

  • 逐幀播放的本質是,播放?幀圖像,然后暫停。
  • 涉及到的函數和變量:
  • step_to_next_frame()
  • is->step = 1時單步播放?幀,然后paused
  • 逐幀播放流程
  • 按s鍵,如果當前處于暫停則啟動播放;
  • 播放?幀數據然后進?暫停狀態
  • 逐幀播放是?戶每按?次s鍵,播放器播放?幀畫面。
  • 逐幀播放實現的?法是:每次按了s鍵,就將狀態切換為播放,播放?幀畫?后,將狀態切換為暫停。
  • 函數調?關系如下:
  • main() --> event_loop() --> step_to_next_frame() --> stream_toggle_pause()
  • 實現代碼?較簡單,如下:
  • static void step_to_next_frame(VideoState *is){/* if the stream is paused unpause it, then step */if (is->paused)stream_toggle_pause(is); // 確保切換到播放狀態,播放?幀畫?is->step = 1;} /* called to display each frame */static void video_refresh(void *opaque, double *remaining_time) {......// 視頻播放if (is->video_st) {......if (is->step && !is->paused)stream_toggle_pause(is); // 逐幀播放模式下,播放?幀畫?后暫停......}......}

    2. 調?量

  • ?量控制的本質:控制采樣點的幅值
  • 靜?,將采樣點數值置為0
  • ?量+,提升采樣點的幅值
  • ?量-,降低采樣點的幅值
  • 1. ffplay控制?量的?式
  • 最??量:輸出解碼后的原始數據
  • 靜?:即是輸出數值為0的數據
  • toggle_mute()
  • 改變?量:通過SDL_MixAudioFormat改變解碼后數據的幅值
  • update_volume()
  • ?如下所示(sdl_audio_callback函數內):
  • 以下是ffplay的?式供參考
  • //根據audio_volume決定如何輸出audio_buf/* 判斷是否為靜音,以及當前音量的大小,如果音量為最大則直接拷貝數據 */// 最大音量則直接拷貝解碼后的原始數據if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)memcpy(stream, (uint8_t *) is->audio_buf + is->audio_buf_index, len1);else {// 先將數據清零,如果不再拷貝新數據給stream,則輸出靜音memset(stream, 0, len1);// 3.調整音量// 不為靜音則通過SDL_MixAudioFormat來調整解碼后數據的幅值來實現音量的變化/* 如果處于mute狀態則直接使用stream填0數據, 暫停時is->audio_buf = NULL */if (!is->muted && is->audio_buf)SDL_MixAudioFormat(stream, (uint8_t *) is->audio_buf + is->audio_buf_index,AUDIO_S16SYS, len1, is->audio_volume);}

    3. 靜?

    static void toggle_mute(VideoState *is){is->muted = !is->muted;} ```go//根據audio_volume決定如何輸出audio_buf/* 判斷是否為靜音,以及當前音量的大小,如果音量為最大則直接拷貝數據 */// 最大音量則直接拷貝解碼后的原始數據if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)memcpy(stream, (uint8_t *) is->audio_buf + is->audio_buf_index, len1);else {// 先將數據清零,如果不再拷貝新數據給stream,則輸出靜音memset(stream, 0, len1);// 3.調整音量// 不為靜音則通過SDL_MixAudioFormat來調整解碼后數據的幅值來實現音量的變化/* 如果處于mute狀態則直接使用stream填0數據, 暫停時is->audio_buf = NULL */if (!is->muted && is->audio_buf)SDL_MixAudioFormat(stream, (uint8_t *) is->audio_buf + is->audio_buf_index,AUDIO_S16SYS, len1, is->audio_volume);}

    總結

    以上是生活随笔為你收集整理的ffplay.c学习-8-暂停、逐帧、⾳量的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。