Browse code

ffplay: add serial field to PacketQueue entry and populate it

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.

Signed-off-by: Marton Balint <cus@passwd.hu>

Marton Balint authored on 2012/10/15 00:56:32
Showing 1 changed files
... ...
@@ -87,11 +87,18 @@ const int program_birth_year = 2003;
87 87
 
88 88
 static int sws_flags = SWS_BICUBIC;
89 89
 
90
+typedef struct MyAVPacketList {
91
+    AVPacket pkt;
92
+    struct MyAVPacketList *next;
93
+    int serial;
94
+} MyAVPacketList;
95
+
90 96
 typedef struct PacketQueue {
91
-    AVPacketList *first_pkt, *last_pkt;
97
+    MyAVPacketList *first_pkt, *last_pkt;
92 98
     int nb_packets;
93 99
     int size;
94 100
     int abort_request;
101
+    int serial;
95 102
     SDL_mutex *mutex;
96 103
     SDL_cond *cond;
97 104
 } PacketQueue;
... ...
@@ -108,6 +115,7 @@ typedef struct VideoPicture {
108 108
     AVRational sample_aspect_ratio;
109 109
     int allocated;
110 110
     int reallocate;
111
+    int serial;
111 112
 
112 113
 #if CONFIG_AVFILTER
113 114
     AVFilterBufferRef *picref;
... ...
@@ -174,6 +182,7 @@ typedef struct VideoState {
174 174
     int audio_write_buf_size;
175 175
     AVPacket audio_pkt_temp;
176 176
     AVPacket audio_pkt;
177
+    int audio_pkt_temp_serial;
177 178
     struct AudioParams audio_src;
178 179
     struct AudioParams audio_tgt;
179 180
     struct SwrContext *swr_ctx;
... ...
@@ -305,16 +314,19 @@ static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
305 305
 
306 306
 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
307 307
 {
308
-    AVPacketList *pkt1;
308
+    MyAVPacketList *pkt1;
309 309
 
310 310
     if (q->abort_request)
311 311
        return -1;
312 312
 
313
-    pkt1 = av_malloc(sizeof(AVPacketList));
313
+    pkt1 = av_malloc(sizeof(MyAVPacketList));
314 314
     if (!pkt1)
315 315
         return -1;
316 316
     pkt1->pkt = *pkt;
317 317
     pkt1->next = NULL;
318
+    if (pkt == &flush_pkt)
319
+        q->serial++;
320
+    pkt1->serial = q->serial;
318 321
 
319 322
     if (!q->last_pkt)
320 323
         q->first_pkt = pkt1;
... ...
@@ -357,7 +369,7 @@ static void packet_queue_init(PacketQueue *q)
357 357
 
358 358
 static void packet_queue_flush(PacketQueue *q)
359 359
 {
360
-    AVPacketList *pkt, *pkt1;
360
+    MyAVPacketList *pkt, *pkt1;
361 361
 
362 362
     SDL_LockMutex(q->mutex);
363 363
     for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
... ...
@@ -399,9 +411,9 @@ static void packet_queue_start(PacketQueue *q)
399 399
 }
400 400
 
401 401
 /* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
402
-static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
402
+static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
403 403
 {
404
-    AVPacketList *pkt1;
404
+    MyAVPacketList *pkt1;
405 405
     int ret;
406 406
 
407 407
     SDL_LockMutex(q->mutex);
... ...
@@ -420,6 +432,8 @@ static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
420 420
             q->nb_packets--;
421 421
             q->size -= pkt1->pkt.size + sizeof(*pkt1);
422 422
             *pkt = pkt1->pkt;
423
+            if (serial)
424
+                *serial = pkt1->serial;
423 425
             av_free(pkt1);
424 426
             ret = 1;
425 427
             break;
... ...
@@ -1169,7 +1183,7 @@ static void pictq_prev_picture(VideoState *is) {
1169 1169
     }
1170 1170
 }
1171 1171
 
1172
-static void update_video_pts(VideoState *is, double pts, int64_t pos) {
1172
+static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1173 1173
     double time = av_gettime() / 1000000.0;
1174 1174
     /* update current video pts */
1175 1175
     is->video_current_pts = pts;
... ...
@@ -1195,7 +1209,7 @@ retry:
1195 1195
         if (is->pictq_size == 0) {
1196 1196
             SDL_LockMutex(is->pictq_mutex);
1197 1197
             if (is->frame_last_dropped_pts != AV_NOPTS_VALUE && is->frame_last_dropped_pts > is->frame_last_pts) {
1198
-                update_video_pts(is, is->frame_last_dropped_pts, is->frame_last_dropped_pos);
1198
+                update_video_pts(is, is->frame_last_dropped_pts, is->frame_last_dropped_pos, 0);
1199 1199
                 is->frame_last_dropped_pts = AV_NOPTS_VALUE;
1200 1200
             }
1201 1201
             SDL_UnlockMutex(is->pictq_mutex);
... ...
@@ -1229,7 +1243,7 @@ retry:
1229 1229
                 is->frame_timer += delay * FFMAX(1, floor((time-is->frame_timer) / delay));
1230 1230
 
1231 1231
             SDL_LockMutex(is->pictq_mutex);
1232
-            update_video_pts(is, vp->pts, vp->pos);
1232
+            update_video_pts(is, vp->pts, vp->pos, vp->serial);
1233 1233
             SDL_UnlockMutex(is->pictq_mutex);
1234 1234
 
1235 1235
             if (is->pictq_size > 1) {
... ...
@@ -1374,7 +1388,7 @@ static void alloc_picture(VideoState *is)
1374 1374
     SDL_UnlockMutex(is->pictq_mutex);
1375 1375
 }
1376 1376
 
1377
-static int queue_picture(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos)
1377
+static int queue_picture(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos, int serial)
1378 1378
 {
1379 1379
     VideoPicture *vp;
1380 1380
     double frame_delay, pts = pts1;
... ...
@@ -1495,6 +1509,7 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts1, int64_
1495 1495
         vp->pts = pts;
1496 1496
         vp->pos = pos;
1497 1497
         vp->skip = 0;
1498
+        vp->serial = serial;
1498 1499
 
1499 1500
         /* now we can update the picture count */
1500 1501
         if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
... ...
@@ -1506,11 +1521,11 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts1, int64_
1506 1506
     return 0;
1507 1507
 }
1508 1508
 
1509
-static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt)
1509
+static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt, int *serial)
1510 1510
 {
1511 1511
     int got_picture, i;
1512 1512
 
1513
-    if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1513
+    if (packet_queue_get(&is->videoq, pkt, 1, serial) < 0)
1514 1514
         return -1;
1515 1515
 
1516 1516
     if (pkt->data == flush_pkt.data) {
... ...
@@ -1682,6 +1697,7 @@ static int video_thread(void *arg)
1682 1682
     int64_t pts_int = AV_NOPTS_VALUE, pos = -1;
1683 1683
     double pts;
1684 1684
     int ret;
1685
+    int serial = 0;
1685 1686
 
1686 1687
 #if CONFIG_AVFILTER
1687 1688
     AVCodecContext *codec = is->video_st->codec;
... ...
@@ -1710,7 +1726,7 @@ static int video_thread(void *arg)
1710 1710
         avcodec_get_frame_defaults(frame);
1711 1711
         av_free_packet(&pkt);
1712 1712
 
1713
-        ret = get_video_frame(is, frame, &pts_int, &pkt);
1713
+        ret = get_video_frame(is, frame, &pts_int, &pkt, &serial);
1714 1714
         if (ret < 0)
1715 1715
             goto the_end;
1716 1716
 
... ...
@@ -1791,11 +1807,11 @@ static int video_thread(void *arg)
1791 1791
                         is->video_st->time_base.num, is->video_st->time_base.den, pts_int);
1792 1792
             }
1793 1793
             pts = pts_int * av_q2d(is->video_st->time_base);
1794
-            ret = queue_picture(is, frame, pts, pos);
1794
+            ret = queue_picture(is, frame, pts, pos, serial);
1795 1795
         }
1796 1796
 #else
1797 1797
         pts = pts_int * av_q2d(is->video_st->time_base);
1798
-        ret = queue_picture(is, frame, pts, pkt.pos);
1798
+        ret = queue_picture(is, frame, pts, pkt.pos, serial);
1799 1799
 #endif
1800 1800
 
1801 1801
         if (ret < 0)
... ...
@@ -1828,7 +1844,7 @@ static int subtitle_thread(void *arg)
1828 1828
         while (is->paused && !is->subtitleq.abort_request) {
1829 1829
             SDL_Delay(10);
1830 1830
         }
1831
-        if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1831
+        if (packet_queue_get(&is->subtitleq, pkt, 1, NULL) < 0)
1832 1832
             break;
1833 1833
 
1834 1834
         if (pkt->data == flush_pkt.data) {
... ...
@@ -2079,7 +2095,7 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr)
2079 2079
             SDL_CondSignal(is->continue_read_thread);
2080 2080
 
2081 2081
         /* read next packet */
2082
-        if ((new_packet = packet_queue_get(&is->audioq, pkt, 1)) < 0)
2082
+        if ((new_packet = packet_queue_get(&is->audioq, pkt, 1, &is->audio_pkt_temp_serial)) < 0)
2083 2083
             return -1;
2084 2084
 
2085 2085
         if (pkt->data == flush_pkt.data) {