1 STATIC
void ctx_lock(void)
5 r
= pthread_mutex_lock(&ctx_mutex_l
);
7 fatal("%d:unable to lock the format context\n", r
);
9 STATIC
void ctx_unlock(void)
13 r
= pthread_mutex_unlock(&ctx_mutex_l
);
15 fatal("%d:unable to unlock the format context\n", r
);
17 STATIC u8
*duration_estimate_to_str(enum avformat_duration_estimation_method_t
21 case avformat_duration_from_pts
:
22 return "from PTS(Presentation TimeStamp)";
23 case avformat_duration_from_st
:
25 case avformat_duration_from_bitrate
:
26 return "from bitrate";
32 #define LIMITS_REACHED 1
35 * we don't want to lock any pkt q for too long, then we do finer-grained
38 STATIC u8
pkts_read_and_q(void) { loop
43 if (did_reached_limits())
44 return LIMITS_REACHED
;
47 /* XXX: there, new streams can appear (could some disappear?) */
49 r
= avformat_read_pkt(ctx_p
, pkt_l
);
51 if (r
== AVERROR(EAGAIN
))
53 else if (r
== AVERROR_EOF
)
58 if (retries_n
== FMT_RETRIES_N
)
59 fatal("ffmpeg:error while reading coded/compressed data into packets\n");
60 warning("ffmpeg:error while reading coded/compressed data into packets, flushing and more, retries = %u(%u)\n", retries_n
, FMT_RETRIES_N
);
63 * XXX: with some trashy iap hls peering, network connectivity (often tls)
64 * errors will make ffmpeg inject eof pkts, clean them even if it may hang
65 * in the case of a legit eof.
67 npv_pkt_q_lock(npv_audio_pkt_q_p
);
68 npv_pkt_q_eofs_cleanup(npv_audio_pkt_q_p
);
69 npv_pkt_q_unlock(npv_audio_pkt_q_p
);
71 npv_pkt_q_lock(npv_video_pkt_q_p
);
72 npv_pkt_q_eofs_cleanup(npv_video_pkt_q_p
);
73 npv_pkt_q_unlock(npv_video_pkt_q_p
);
81 if (pkt_l
->st_idx
== npv_audio_st_p
.idx
) {
82 npv_pipeline_limits_lock();
83 npv_pipeline_limits_p
.pkts
.bytes_n
+= (u64
)pkt_l
->sz
;
84 if (npv_pipeline_limits_p
.pkts
.prefill
.bytes_rem
> 0)
85 npv_pipeline_limits_p
.pkts
.prefill
.bytes_rem
-= (s64
)pkt_l
->sz
;
86 npv_pipeline_limits_unlock();
88 npv_pkt_q_lock(npv_audio_pkt_q_p
);
89 /* will "steal" the pkt */
90 npv_pkt_q_enq(npv_audio_pkt_q_p
, pkt_l
);
91 npv_pkt_q_unlock(npv_audio_pkt_q_p
);
92 } else if (pkt_l
->st_idx
== npv_video_st_p
.idx
) {
93 npv_pipeline_limits_lock();
94 npv_pipeline_limits_p
.pkts
.bytes_n
+= (u64
)pkt_l
->sz
;
95 if (npv_pipeline_limits_p
.pkts
.prefill
.bytes_rem
> 0)
96 npv_pipeline_limits_p
.pkts
.prefill
.bytes_rem
-= (s64
)pkt_l
->sz
;
97 npv_pipeline_limits_unlock();
99 npv_pkt_q_lock(npv_video_pkt_q_p
);
100 /* will "steal" the pkt */
101 npv_pkt_q_enq(npv_video_pkt_q_p
, pkt_l
);
102 npv_pkt_q_unlock(npv_video_pkt_q_p
);
103 } else /* data, subtitles, non active sts, etc */
104 avcodec_pkt_unref(pkt_l
);
107 #undef LIMITS_REACHED
109 STATIC
void probe_best_sts(
110 int *best_v_idx
, int *best_v_id
, avutil_rational_t
**best_v_tb
,
111 int64_t *best_v_start_time
, avcodec_params_t
**best_v_codec_params
,
112 int *best_a_idx
, int *best_a_id
, avutil_rational_t
**best_a_tb
,
113 int64_t *best_a_start_time
, avcodec_params_t
**best_a_codec_params
)
117 /* probe beyond the header, if any */
118 r
= avformat_find_st_info(ctx_p
, 0);
120 fatal("ffmpeg:unable to probe\n");
121 r
= avformat_find_best_st(ctx_p
, AVUTIL_AVMEDIA_TYPE_AUDIO
, -1, -1, 0,
124 fatal("ffmpeg:no audio stream found\n");
125 /* we copy what we need */
127 *best_a_id
= ctx_p
->sts
[r
]->id
;
128 *best_a_tb
= &ctx_p
->sts
[r
]->tb
;
129 *best_a_start_time
= ctx_p
->sts
[r
]->start_time
;
130 *best_a_codec_params
= ctx_p
->sts
[r
]->codecpar
; /* used once for init */
132 r
= avformat_find_best_st(ctx_p
, AVUTIL_AVMEDIA_TYPE_VIDEO
, -1, -1, 0,
135 fatal("ffmpeg:no video stream found\n");
136 /* we copy what we need */
138 *best_v_id
= ctx_p
->sts
[r
]->id
;
139 *best_v_tb
= &ctx_p
->sts
[r
]->tb
;
140 *best_v_start_time
= ctx_p
->sts
[r
]->start_time
;
141 *best_v_codec_params
= ctx_p
->sts
[r
]->codecpar
; /* used once for init */
142 pout("####%s#### probing: %u streams and %u programs\n", ctx_p
->url
, ctx_p
->sts_n
, ctx_p
->programs_n
);
143 pout("####%s#### probing: best video stream index=%d/id=%d, best audio stream index=%d/id=%d\n", ctx_p
->url
, *best_v_idx
, *best_v_id
, *best_a_idx
, *best_a_id
);
145 STATIC
void flush(void)
147 avformat_flush(ctx_p
);
148 avio_flush(ctx_p
->pb
);
150 STATIC
void init_once(u8
*url
)
152 init_once_public(url
);