亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? tutorial06.java

?? ffmpeg開發(fā)指南
?? JAVA
字號:
## An ffmpeg and SDL TutorialPage 1 2 3 4 5 6 7 8 End Prev Home NextPrintable version Text version## Tutorial 06: Synching AudioCode: tutorial06.c### Synching AudioSo now we have a decent enough player to watch a movie, so let's see what kindof loose ends we have lying around. Last time, we glossed over synchronizationa little bit, namely sychronizing audio to a video clock rather than the otherway around. We're going to do this the same way as with the video: make aninternal video clock to keep track of how far along the video thread is andsync the audio to that. Later we'll look at how to generalize things to syncboth audio and video to an external clock, too.### Implementing the video clockNow we want to implement a video clock similar to the audio clock we had lasttime: an internal value that gives the current time offset of the videocurrently being played. At first, you would think that this would be as simpleas updating the timer with the current PTS of the last frame to be shown.However, don't forget that the time between video frames can be pretty longwhen we get down to the millisecond level. The solution is to keep track ofanother value, the time at which we set the video clock to the PTS of the lastframe. That way the current value of the video clock will be PTS_of_last_frame+ (current_time - time_elapsed_since_PTS_value_was_set). This solution is verysimilar to what we did with get_audio_clock.So, in our big struct, we're going to put a double video_current_pts and aint64_t video_current_pts_time. The clock updating is going to take place inthe video_refresh_timer function:    void video_refresh_timer(void *userdata) {      /* ... */      if(is->video_st) {        if(is->pictq_size == 0) {          schedule_refresh(is, 1);        } else {          vp = &is->pictq[is->pictq_rindex];          is->video_current_pts = vp->pts;          is->video_current_pts_time = av_gettime();Don't forget to initialize it in stream_component_open:        is->video_current_pts_time = av_gettime();And now all we need is a way to get the information:    double get_video_clock(VideoState *is) {      double delta;      delta = (av_gettime() - is->video_current_pts_time) / 1000000.0;      return is->video_current_pts + delta;    }### Abstracting the clockBut why force ourselves to use the video clock? We'd have to go and alter ourvideo sync code so that the audio and video aren't trying to sync to eachother. Imagine the mess if we tried to make it a command line option like itis in ffplay. So let's abstract things: we're going to make a new wrapperfunction, get_master_clock that checks an av_sync_type variable and then callget_audio_clock, get_video_clock, or whatever other clock we want to use. Wecould even use the computer clock, which we'll call get_external_clock:    enum {      AV_SYNC_AUDIO_MASTER,      AV_SYNC_VIDEO_MASTER,      AV_SYNC_EXTERNAL_MASTER,    };    #define DEFAULT_AV_SYNC_TYPE AV_SYNC_VIDEO_MASTER    double get_master_clock(VideoState *is) {      if(is->av_sync_type == AV_SYNC_VIDEO_MASTER) {        return get_video_clock(is);      } else if(is->av_sync_type == AV_SYNC_AUDIO_MASTER) {        return get_audio_clock(is);      } else {        return get_external_clock(is);      }    }    main() {    ...      is->av_sync_type = DEFAULT_AV_SYNC_TYPE;    ...    }### Synchronizing the AudioNow the hard part: synching the audio to the video clock. Our strategy isgoing to be to measure where the audio is, compare it to the video clock, andthen figure out how many samples we need to adjust by, that is, do we need tospeed up by dropping samples or do we need to slow down by adding them?We're going to run a synchronize_audio function each time we process each setof audio samples we get to shrink or expand them properly. However, we don'twant to sync every single time it's off because process audio a lot more oftenthan video packets. So we're going to set a minimum number of consecutivecalls to the synchronize_audio function that have to be out of sync before webother doing anything. Of course, just like last time, "out of sync" meansthat the audio clock and the video clock differ by more than our syncthreshold.**Note:** What the heck is going on here? This equation looks like magic!Well, it's basically a weighted mean using a geometric series as weights. Idon't know if there's a name for this (I even checked Wikipedia!) but for moreinfo, here's an explanation (or at weightedmean.txt) So we're going to use afractional coefficient, say c, and So now let's say we've gotten N audiosample sets that have been out of sync. The amount we are out of sync can alsovary a good deal, so we're going to take an average of how far each of thosehave been out of sync. So for example, the first call might have shown we wereout of sync by 40ms, the next by 50ms, and so on. But we're not going to takea simple average because the most recent values are more important than theprevious ones. So we're going to use a fractional coefficient, say c, and sumthe differences like this: diff_sum = new_diff + diff_sum*c. When we are readyto find the average difference, we simply calculate avg_diff = diff_sum *(1-c).Here's what our function looks like so far:    /* Add or subtract samples to get a better sync, return new       audio buffer size */    int synchronize_audio(VideoState *is, short *samples,    		      int samples_size, double pts) {      int n;      double ref_clock;      n = 2 * is->audio_st->codec->channels;      if(is->av_sync_type != AV_SYNC_AUDIO_MASTER) {        double diff, avg_diff;        int wanted_size, min_size, max_size, nb_samples;        ref_clock = get_master_clock(is);        diff = get_audio_clock(is) - ref_clock;        if(diff < AV_NOSYNC_THRESHOLD) {          // accumulate the diffs          is->audio_diff_cum = diff + is->audio_diff_avg_coef    	* is->audio_diff_cum;          if(is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {    	is->audio_diff_avg_count++;          } else {    	avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);           /* Shrinking/expanding buffer code.... */          }        } else {          /* difference is TOO big; reset diff stuff */          is->audio_diff_avg_count = 0;          is->audio_diff_cum = 0;        }      }      return samples_size;    }So we're doing pretty well; we know approximately how off the audio is fromthe video or whatever we're using for a clock. So let's now calculate how manysamples we need to add or lop off by putting this code where the"Shrinking/expanding buffer code" section is:    if(fabs(avg_diff) >= is->audio_diff_threshold) {      wanted_size = samples_size +      ((int)(diff * is->audio_st->codec->sample_rate) * n);      min_size = samples_size * ((100 - SAMPLE_CORRECTION_PERCENT_MAX)                                 / 100);      max_size = samples_size * ((100 + SAMPLE_CORRECTION_PERCENT_MAX)                                 / 100);      if(wanted_size < min_size) {        wanted_size = min_size;      } else if (wanted_size > max_size) {        wanted_size = max_size;      }Remember that audio_length * (sample_rate * # of channels * 2) is the numberof samples in audio_length seconds of audio. Therefore, number of samples wewant is going to be the number of samples we already have plus or minus thenumber of samples that correspond to the amount of time the audio has drifted.We'll also set a limit on how big or small our correction can be because if wechange our buffer too much, it'll be too jarring to the user.### Correcting the number of samplesNow we have to actually correct the audio. You may have noticed that oursynchronize_audio function returns a sample size, which will then tell us howmany bytes to send to the stream. So we just have to adjust the sample size tothe wanted_size. This works for making the sample size smaller. But if we wantto make it bigger, we can't just make the sample size larger because there'sno more data in the buffer! So we have to add it. But what should we add? Itwould be foolish to try and extrapolate audio, so let's just use the audio wealready have by padding out the buffer with the value of the last sample.    if(wanted_size < samples_size) {      /* remove samples */      samples_size = wanted_size;    } else if(wanted_size > samples_size) {      uint8_t *samples_end, *q;      int nb;      /* add samples by copying final samples */      nb = (samples_size - wanted_size);      samples_end = (uint8_t *)samples + samples_size - n;      q = samples_end + n;      while(nb > 0) {        memcpy(q, samples_end, n);        q += n;        nb -= n;      }      samples_size = wanted_size;    }Now we return the sample size, and we're done with that function. All we needto do now is use it:    void audio_callback(void *userdata, Uint8 *stream, int len) {      VideoState *is = (VideoState *)userdata;      int len1, audio_size;      double pts;      while(len > 0) {        if(is->audio_buf_index >= is->audio_buf_size) {          /* We have already sent all our data; get more */          audio_size = audio_decode_frame(is, is->audio_buf,sizeof(is->audio_buf), &pts);          if(audio_size < 0) {    	/* If error, output silence */    	is->audio_buf_size = 1024;    	memset(is->audio_buf, 0, is->audio_buf_size);          } else {    	audio_size = synchronize_audio(is, (int16_t *)is->audio_buf,    				       audio_size, pts);    	is->audio_buf_size = audio_size;All we did is inserted the call to synchronize_audio. (Also, make sure tocheck the source code where we initalize the above variables I didn't botherto define.)One last thing before we finish: we need to add an if clause to make sure wedon't sync the video if it is the master clock:    if(is->av_sync_type != AV_SYNC_VIDEO_MASTER) {      ref_clock = get_master_clock(is);      diff = vp->pts - ref_clock;      /* Skip or repeat the frame. Take delay into account         FFPlay still doesn't "know if this is the best guess." */      sync_threshold = (delay > AV_SYNC_THRESHOLD) ? delay :                        AV_SYNC_THRESHOLD;      if(fabs(diff) < AV_NOSYNC_THRESHOLD) {        if(diff <= -sync_threshold) {          delay = 0;        } else if(diff >= sync_threshold) {          delay = 2 * delay;        }      }    }And that does it! Make sure you check through the source file to initializeany variables that I didn't bother defining or initializing. Then compile it:    gcc -o tutorial06 tutorial06.c -lavutil -lavformat -lavcodec -lz-lm`sdl-config --cflags --libs`and you'll be good to go.Next time we'll make it so you can rewind and fast forward your movie._**>>** Seeking_* * *Function ReferenceData Referenceemail:dranger at gmail dot comBack to dranger.comThis work is licensed under the Creative Commons Attribution-Share Alike 2.5License. To view a copy of this license, visithttp://creativecommons.org/licenses/by-sa/2.5/ or send a letter to CreativeCommons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA.Code examples are based off of FFplay, Copyright (c) 2003 Fabrice Bellard, anda tutorial by Martin Bohme.

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
久色婷婷小香蕉久久| 青青草原综合久久大伊人精品优势| 亚洲视频在线一区| 蜜桃精品在线观看| 色综合婷婷久久| 久久久夜色精品亚洲| 视频一区在线播放| 成人免费黄色在线| 精品国产乱码久久久久久夜甘婷婷| 亚洲丝袜另类动漫二区| 一本色道久久综合精品竹菊| 精品国产91乱码一区二区三区| 麻豆精品视频在线观看视频| 久久人人爽爽爽人久久久| 国内精品第一页| 欧美一级二级三级乱码| 亚洲国产视频在线| 在线观看视频91| 激情综合网激情| 337p亚洲精品色噜噜| 亚洲一区二区免费视频| 91视视频在线观看入口直接观看www | 久久亚洲一级片| 青青草国产精品亚洲专区无| 2020国产精品自拍| 91美女视频网站| 日韩高清欧美激情| 欧美一级片在线看| 日本伊人精品一区二区三区观看方式| 精品日韩成人av| 国产在线国偷精品免费看| 日韩精品中文字幕一区二区三区| 视频一区中文字幕| 国产女人水真多18毛片18精品视频| 国产一区二区导航在线播放| 亚洲少妇中出一区| 欧美videossexotv100| 色婷婷综合久色| 裸体一区二区三区| 亚洲视频狠狠干| 日韩免费电影一区| 欧美午夜宅男影院| 亚洲18色成人| 欧美一区二区三区免费大片| 国产综合色在线视频区| 亚洲图片欧美综合| 中文字幕高清不卡| 日本精品一区二区三区高清| 亚洲午夜久久久久中文字幕久| 精品国产一区二区三区不卡| 日本韩国欧美在线| 国产成人精品一区二区三区四区| 国产欧美一区二区精品秋霞影院| 欧美性色黄大片手机版| 成人开心网精品视频| 日韩av不卡在线观看| 一区二区日韩av| 91精品中文字幕一区二区三区| www.av精品| 天天综合日日夜夜精品| 精品久久久久久久久久久久久久久久久| 色综合婷婷久久| 国产99久久久国产精品| 夜夜揉揉日日人人青青一国产精品| 国产亚洲女人久久久久毛片| 一本到一区二区三区| 成人免费毛片高清视频| 国产一区美女在线| 免费成人小视频| 免费高清视频精品| 免费在线观看一区二区三区| 亚洲国产aⅴ天堂久久| 一区二区三区四区中文字幕| 亚洲色欲色欲www| √…a在线天堂一区| 欧美一级视频精品观看| 欧美另类一区二区三区| 国产suv精品一区二区6| 精品亚洲欧美一区| 国产真实精品久久二三区| 麻豆精品一区二区| 狠狠色狠狠色综合日日91app| 奇米在线7777在线精品| 午夜精品一区在线观看| 婷婷开心久久网| 天使萌一区二区三区免费观看| 婷婷综合五月天| 日本91福利区| 麻豆国产91在线播放| 国产在线不卡一区| 岛国av在线一区| 97se亚洲国产综合自在线观| 国产露脸91国语对白| 亚洲成a人片在线观看中文| 午夜国产精品影院在线观看| 午夜亚洲国产au精品一区二区| 亚洲成人tv网| 男人操女人的视频在线观看欧美| 久热成人在线视频| 国产福利一区二区三区视频在线| www.av精品| 欧美三级蜜桃2在线观看| 99国产精品一区| 欧美日韩国产首页| 91高清视频免费看| 欧美人狂配大交3d怪物一区| 日韩欧美在线影院| 久久精品一区八戒影视| 国产精品毛片无遮挡高清| 国产日韩欧美制服另类| 亚洲美女视频一区| 亚洲视频在线观看三级| 天堂成人免费av电影一区| 黄色成人免费在线| 99国产精品99久久久久久| 欧美另类z0zxhd电影| 久久综合资源网| 依依成人精品视频| 一区二区激情小说| 久久精品二区亚洲w码| heyzo一本久久综合| 911精品产国品一二三产区| 久久久国产精华| 亚洲高清三级视频| 国产精品 日产精品 欧美精品| 91激情在线视频| 国产偷国产偷亚洲高清人白洁| 有码一区二区三区| 国产精品亚洲а∨天堂免在线| 在线视频你懂得一区二区三区| 欧美成人a视频| 亚洲午夜羞羞片| 国产69精品久久777的优势| 欧美猛男gaygay网站| 中文字幕+乱码+中文字幕一区| 日韩中文字幕不卡| 91麻豆精品一区二区三区| www一区二区| 舔着乳尖日韩一区| 99精品国产视频| 国产欧美精品日韩区二区麻豆天美| 午夜电影网一区| 91麻豆免费观看| 日韩一区二区在线观看视频| 亚洲综合在线视频| 成人黄色软件下载| 91浏览器入口在线观看| 久久看人人爽人人| 麻豆高清免费国产一区| 678五月天丁香亚洲综合网| 亚洲欧美另类小说| 99国内精品久久| 国产午夜久久久久| 国产综合成人久久大片91| 欧美国产日韩一二三区| 久久精品国产99国产精品| 91 com成人网| 日韩精品一级中文字幕精品视频免费观看| www.亚洲精品| 亚洲欧美在线高清| 国产成人精品亚洲777人妖| 久久久蜜桃精品| 国产毛片精品视频| wwwwww.欧美系列| 久久er99热精品一区二区| 91精品国产全国免费观看| 日韩av一区二区三区四区| 制服.丝袜.亚洲.中文.综合| 亚洲成人黄色影院| 欧美日韩亚洲综合在线| 亚洲综合免费观看高清在线观看| 一本到不卡精品视频在线观看| 亚洲男人的天堂在线aⅴ视频| 91色视频在线| 亚洲一二三四在线| 欧美丰满少妇xxxxx高潮对白| 午夜精品福利一区二区三区av| 91精品一区二区三区久久久久久 | 国产精品久久网站| 一区二区久久久| 在线亚洲精品福利网址导航| 亚洲一区在线观看视频| 欧美伊人精品成人久久综合97| 亚洲一区在线看| 337p亚洲精品色噜噜狠狠| 免费一级欧美片在线观看| 日韩欧美在线123| 国模一区二区三区白浆 | 日本一二三四高清不卡| 国产成a人亚洲| 综合激情网...| 欧美亚洲动漫另类| 日本成人在线一区| 欧美精品一区二区三区蜜桃视频| 国产精品1区二区.| 亚洲乱码国产乱码精品精的特点 | 午夜精品久久久久久久99樱桃 | 精品少妇一区二区三区在线视频| 黑人巨大精品欧美一区| 中文字幕一区免费在线观看|