91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

FFmpeg ffplay serial剖析

發布時間:2020-08-05 17:57:49 來源:網絡 閱讀:506 作者:fengyuzaitu 欄目:軟件技術

Serial has two purposes nowadays: the initial purpose in the commit was to be able to distinguish packets in the packet queue from before and after a seek. The demuxer (input for packet queue) runs in a separate thread. After a seek, we want to flush it, but we don't want to stop the producer thread because overhead. However, we also don't want to flush too few or too many packets. So, the serial field tells us which packets are pre- and post-flush and thus which packets to drop without having to stop the producer thread while we're dropping those packets.
The second purpose is your line of code: it tells us when EOF occurs. Finished is set to the last serial number of a packet from the packet queue used to decode a frame. If that serial number is also the tail of the packet queue (and no more packets are produced), it means we stopped producing packets and decoded the frame belonging to that packet. In other words: end-of-file. Elsewhere, you'll find a test along those lines, and then either playback stops or (if looping is enabled) we seek back to the beginning of the file (i.e. invoke the looping behaviour).
(This write-up was helpfully assisted by several FFmpeg developers on IRC.)


The purpose of the serial field is to accompany the decoded data during the
decoding process to know if the decoded data belongs to the data stream after
the latest packet queue flush.

代碼

?static int sws_flags = SWS_BICUBIC;
?
+typedef struct MyAVPacketList {
+??? AVPacket pkt;
+??? struct MyAVPacketList *next;
+??? int serial;
+} MyAVPacketList;
+
?typedef struct PacketQueue {
-??? AVPacketList *first_pkt, *last_pkt;
+??? MyAVPacketList *first_pkt, *last_pkt;
???? int nb_packets;
???? int size;
???? int abort_request;
+??? int serial;
???? SDL_mutex *mutex;
???? SDL_cond *cond;
?} PacketQueue;
@@ -108,6 +115,7 @@ typedef struct VideoPicture {
???? AVRational sample_aspect_ratio;
???? int allocated;
???? int reallocate;
+??? int serial;
?
?#if CONFIG_AVFILTER
???? AVFilterBufferRef *picref;
@@ -174,6 +182,7 @@ typedef struct VideoState {
???? int audio_write_buf_size;
???? AVPacket audio_pkt_temp;
???? AVPacket audio_pkt;
+??? int audio_pkt_temp_serial;
???? struct AudioParams audio_src;
???? struct AudioParams audio_tgt;
???? struct SwrContext *swr_ctx;
@@ -305,16 +314,19 @@ static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
?
?static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
?{
-??? AVPacketList *pkt1;
+??? MyAVPacketList *pkt1;
?
???? if (q->abort_request)
??????? return -1;
?
-??? pkt1 = av_malloc(sizeof(AVPacketList));
+??? pkt1 = av_malloc(sizeof(MyAVPacketList));
???? if (!pkt1)
???????? return -1;
???? pkt1->pkt = *pkt;
???? pkt1->next = NULL;
+??? if (pkt == &flush_pkt)
+??????? q->serial++;
+??? pkt1->serial = q->serial;
?
???? if (!q->last_pkt)
???????? q->first_pkt = pkt1;
@@ -357,7 +369,7 @@ static void packet_queue_init(PacketQueue *q)
?
?static void packet_queue_flush(PacketQueue *q)
?{
-??? AVPacketList *pkt, *pkt1;
+??? MyAVPacketList *pkt, *pkt1;
?
???? SDL_LockMutex(q->mutex);
???? for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
@@ -399,9 +411,9 @@ static void packet_queue_start(PacketQueue *q)
?}
?
?/* return < 0 if aborted, 0 if no packet and > 0 if packet.? */
-static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
+static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
?{
-??? AVPacketList *pkt1;
+??? MyAVPacketList *pkt1;
???? int ret;
?
???? SDL_LockMutex(q->mutex);
@@ -420,6 +432,8 @@ static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
???????????? q->nb_packets--;
???????????? q->size -= pkt1->pkt.size + sizeof(*pkt1);
???????????? *pkt = pkt1->pkt;
+??????????? if (serial)
+??????????????? *serial = pkt1->serial;
???????????? av_free(pkt1);
???????????? ret = 1;
???????????? break;
@@ -1169,7 +1183,7 @@ static void pictq_prev_picture(VideoState *is) {
???? }
?}
?
-static void update_video_pts(VideoState *is, double pts, int64_t pos) {
+static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
???? double time = av_gettime() / 1000000.0;
???? /* update current video pts */
???? is->video_current_pts = pts;
@@ -1195,7 +1209,7 @@ retry:
???????? if (is->pictq_size == 0) {
???????????? SDL_LockMutex(is->pictq_mutex);
???????????? if (is->frame_last_dropped_pts != AV_NOPTS_VALUE && is->frame_last_dropped_pts > is->frame_last_pts) {
-??????????????? update_video_pts(is, is->frame_last_dropped_pts, is->frame_last_dropped_pos);
+??????????????? update_video_pts(is, is->frame_last_dropped_pts, is->frame_last_dropped_pos, 0);
???????????????? is->frame_last_dropped_pts = AV_NOPTS_VALUE;
???????????? }
???????????? SDL_UnlockMutex(is->pictq_mutex);
@@ -1229,7 +1243,7 @@ retry:
???????????????? is->frame_timer += delay * FFMAX(1, floor((time-is->frame_timer) / delay));
?
???????????? SDL_LockMutex(is->pictq_mutex);
-??????????? update_video_pts(is, vp->pts, vp->pos);
+??????????? update_video_pts(is, vp->pts, vp->pos, vp->serial);
???????????? SDL_UnlockMutex(is->pictq_mutex);
?
???????????? if (is->pictq_size > 1) {
@@ -1374,7 +1388,7 @@ static void alloc_picture(VideoState *is)
???? SDL_UnlockMutex(is->pictq_mutex);
?}
?
-static int queue_picture(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos)
+static int queue_picture(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos, int serial)
?{
???? VideoPicture *vp;
???? double frame_delay, pts = pts1;
@@ -1495,6 +1509,7 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts1, int64_
???????? vp->pts = pts;
???????? vp->pos = pos;
???????? vp->skip = 0;
+??????? vp->serial = serial;
?
???????? /* now we can update the picture count */
???????? if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
@@ -1506,11 +1521,11 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts1, int64_
???? return 0;
?}
?
-static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt)
+static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt, int *serial)
?{
???? int got_picture, i;
?
-??? if (packet_queue_get(&is->videoq, pkt, 1) < 0)
+??? if (packet_queue_get(&is->videoq, pkt, 1, serial) < 0)
???????? return -1;
?
???? if (pkt->data == flush_pkt.data) {
@@ -1682,6 +1697,7 @@ static int video_thread(void *arg)
???? int64_t pts_int = AV_NOPTS_VALUE, pos = -1;
???? double pts;
???? int ret;
+??? int serial = 0;
?
?#if CONFIG_AVFILTER
???? AVCodecContext *codec = is->video_st->codec;
@@ -1710,7 +1726,7 @@ static int video_thread(void *arg)
???????? avcodec_get_frame_defaults(frame);
???????? av_free_packet(&pkt);
?
-??????? ret = get_video_frame(is, frame, &pts_int, &pkt);
+??????? ret = get_video_frame(is, frame, &pts_int, &pkt, &serial);
???????? if (ret < 0)
???????????? goto the_end;
?
@@ -1791,11 +1807,11 @@ static int video_thread(void *arg)
???????????????????????? is->video_st->time_base.num, is->video_st->time_base.den, pts_int);
???????????? }
???????????? pts = pts_int * av_q2d(is->video_st->time_base);
-??????????? ret = queue_picture(is, frame, pts, pos);
+??????????? ret = queue_picture(is, frame, pts, pos, serial);
???????? }
?#else
???????? pts = pts_int * av_q2d(is->video_st->time_base);
-??????? ret = queue_picture(is, frame, pts, pkt.pos);
+??????? ret = queue_picture(is, frame, pts, pkt.pos, serial);
?#endif
?
???????? if (ret < 0)
@@ -1828,7 +1844,7 @@ static int subtitle_thread(void *arg)
???????? while (is->paused && !is->subtitleq.abort_request) {
???????????? SDL_Delay(10);
???????? }
-??????? if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
+??????? if (packet_queue_get(&is->subtitleq, pkt, 1, NULL) < 0)
???????????? break;
?
???????? if (pkt->data == flush_pkt.data) {
@@ -2079,7 +2095,7 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr)
???????????? SDL_CondSignal(is->continue_read_thread);
?
???????? /* read next packet */
-??????? if ((new_packet = packet_queue_get(&is->audioq, pkt, 1)) < 0)
+??????? if ((new_packet = packet_queue_get(&is->audioq, pkt, 1, &is->audio_pkt_temp_serial)) < 0)
???????????? return -1;
?
???????? if (pkt->data == flush_pkt.data) {


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

札达县| 南木林县| 原平市| 梁平县| 萨迦县| 两当县| 乌恰县| 额济纳旗| 大洼县| 前郭尔| 故城县| 德昌县| 怀宁县| 湛江市| 陈巴尔虎旗| 五莲县| 佛坪县| 汤原县| 来凤县| 皮山县| 佛教| 综艺| 调兵山市| 江西省| 乐陵市| 望江县| 方山县| 保靖县| 临朐县| 明光市| 武定县| 汝城县| 凤城市| 丹凤县| 扎赉特旗| 阿勒泰市| 孟连| 宁津县| 新营市| 崇仁县| 工布江达县|