Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

FFmpeg ffplay serial analysis

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/03 Report--

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.

Code

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, typedef struct VideoPicture 6 + 115, 7 @ @

AVRational sample_aspect_ratio

Int allocated

Int reallocate

+ int serial

# if CONFIG_AVFILTER

AVFilterBufferRef * picref

@ @-174, typedef struct VideoState 6 + 182, 7 @ @

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 PacketQueue 16 + 314 pkt 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 static void packet_queue_init 7 + 369pm 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) {

@ @-399pr 9 + 411 Jol 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)

@ @-420pkt 6 + 432 static int packet_queue_get 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 is 7 + 1183 is 7 @ @ static void pictq_prev_picture (VideoState *) {

}

}

-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

@ @-1195pr 7 + 1209pr 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)

@ @-1229Pol 7 + 1243Pol 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 is 7 + 1388 is 7 @ @ static void alloc_picture

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 double pts1 6 + 1509 static int queue_picture 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 is 11 + 1521 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 (& is- > videoq, pkt, 1)

< 0) + if (packet_queue_get(&is->

Videoq, pkt, 1, serial)

< 0) return -1; if (pkt->

Data = = flush_pkt.data) {

@ @-1682 void 6 + 1697 arg 7 @ @ static int video_thread

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 arg 7 + 1726 arg 7 @ @ static int video_thread

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 (& is- > subtitleq, pkt, 1)

< 0) + if (packet_queue_get(&is->

Subtitleq, pkt, 1, NULL)

< 0) break; if (pkt->

Data = = flush_pkt.data) {

@ @-2079 is 7 + 2095 is 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) {

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report