You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

509 lines
17KB

  1. /*
  2. * seek utility functions for use within format handlers
  3. *
  4. * Copyright (c) 2009 Ivan Schreter
  5. *
  6. * This file is part of FFmpeg.
  7. *
  8. * FFmpeg is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * FFmpeg is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with FFmpeg; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. #include <stdint.h>
  23. #include "seek.h"
  24. #include "libavutil/mathematics.h"
  25. #include "libavutil/mem.h"
  26. #include "internal.h"
  27. // NOTE: implementation should be moved here in another patch, to keep patches
  28. // separated.
  29. /**
  30. * helper structure describing keyframe search state of one stream
  31. */
  32. typedef struct {
  33. int64_t pos_lo; ///< position of the frame with low timestamp in file or INT64_MAX if not found (yet)
  34. int64_t ts_lo; ///< frame presentation timestamp or same as pos_lo for byte seeking
  35. int64_t pos_hi; ///< position of the frame with high timestamp in file or INT64_MAX if not found (yet)
  36. int64_t ts_hi; ///< frame presentation timestamp or same as pos_hi for byte seeking
  37. int64_t last_pos; ///< last known position of a frame, for multi-frame packets
  38. int64_t term_ts; ///< termination timestamp (which TS we already read)
  39. AVRational term_ts_tb; ///< timebase for term_ts
  40. int64_t first_ts; ///< first packet timestamp in this iteration (to fill term_ts later)
  41. AVRational first_ts_tb; ///< timebase for first_ts
  42. int terminated; ///< termination flag for the current iteration
  43. } AVSyncPoint;
  44. /**
  45. * Compute a distance between timestamps.
  46. *
  47. * Distances are only comparable, if same time bases are used for computing
  48. * distances.
  49. *
  50. * @param ts_hi high timestamp
  51. * @param tb_hi high timestamp time base
  52. * @param ts_lo low timestamp
  53. * @param tb_lo low timestamp time base
  54. * @return representation of distance between high and low timestamps
  55. */
  56. static int64_t ts_distance(int64_t ts_hi,
  57. AVRational tb_hi,
  58. int64_t ts_lo,
  59. AVRational tb_lo)
  60. {
  61. int64_t hi, lo;
  62. hi = ts_hi * tb_hi.num * tb_lo.den;
  63. lo = ts_lo * tb_lo.num * tb_hi.den;
  64. return hi - lo;
  65. }
  66. /**
  67. * Partial search for keyframes in multiple streams.
  68. *
  69. * This routine searches in each stream for the next lower and the next higher
  70. * timestamp compared to the given target timestamp. The search starts at the current
  71. * file position and ends at the file position, where all streams have already been
  72. * examined (or when all higher key frames are found in the first iteration).
  73. *
  74. * This routine is called iteratively with an exponential backoff to find the lower
  75. * timestamp.
  76. *
  77. * @param s format context
  78. * @param timestamp target timestamp (or position, if AVSEEK_FLAG_BYTE)
  79. * @param timebase time base for timestamps
  80. * @param flags seeking flags
  81. * @param sync array with information per stream
  82. * @param keyframes_to_find count of keyframes to find in total
  83. * @param found_lo ptr to the count of already found low timestamp keyframes
  84. * @param found_hi ptr to the count of already found high timestamp keyframes
  85. * @param first_iter flag for first iteration
  86. */
  87. static void search_hi_lo_keyframes(AVFormatContext *s,
  88. int64_t timestamp,
  89. AVRational timebase,
  90. int flags,
  91. AVSyncPoint *sync,
  92. int keyframes_to_find,
  93. int *found_lo,
  94. int *found_hi,
  95. int first_iter)
  96. {
  97. AVPacket pkt;
  98. AVSyncPoint *sp;
  99. AVStream *st;
  100. int idx;
  101. int flg;
  102. int terminated_count = 0;
  103. int64_t pos;
  104. int64_t pts, dts; // PTS/DTS from stream
  105. int64_t ts; // PTS in stream-local time base or position for byte seeking
  106. AVRational ts_tb; // Time base of the stream or 1:1 for byte seeking
  107. for (;;) {
  108. if (av_read_frame(s, &pkt) < 0) {
  109. // EOF or error, make sure high flags are set
  110. for (idx = 0; idx < s->nb_streams; ++idx) {
  111. if (s->streams[idx]->discard < AVDISCARD_ALL) {
  112. sp = &sync[idx];
  113. if (sp->pos_hi == INT64_MAX) {
  114. // no high frame exists for this stream
  115. (*found_hi)++;
  116. sp->ts_hi = INT64_MAX;
  117. sp->pos_hi = INT64_MAX - 1;
  118. }
  119. }
  120. }
  121. break;
  122. }
  123. idx = pkt.stream_index;
  124. st = s->streams[idx];
  125. if (st->discard >= AVDISCARD_ALL)
  126. // this stream is not active, skip packet
  127. continue;
  128. sp = &sync[idx];
  129. flg = pkt.flags;
  130. pos = pkt.pos;
  131. pts = pkt.pts;
  132. dts = pkt.dts;
  133. if (pts == AV_NOPTS_VALUE)
  134. // some formats don't provide PTS, only DTS
  135. pts = dts;
  136. av_free_packet(&pkt);
  137. // Multi-frame packets only return position for the very first frame.
  138. // Other frames are read with position == -1. Therefore, we note down
  139. // last known position of a frame and use it if a frame without
  140. // position arrives. In this way, it's possible to seek to proper
  141. // position. Additionally, for parsers not providing position at all,
  142. // an approximation will be used (starting position of this iteration).
  143. if (pos < 0)
  144. pos = sp->last_pos;
  145. else
  146. sp->last_pos = pos;
  147. // Evaluate key frames with known TS (or any frames, if AVSEEK_FLAG_ANY set).
  148. if (pts != AV_NOPTS_VALUE &&
  149. ((flg & AV_PKT_FLAG_KEY) || (flags & AVSEEK_FLAG_ANY))) {
  150. if (flags & AVSEEK_FLAG_BYTE) {
  151. // for byte seeking, use position as timestamp
  152. ts = pos;
  153. ts_tb.num = 1;
  154. ts_tb.den = 1;
  155. } else {
  156. // otherwise, get stream time_base
  157. ts = pts;
  158. ts_tb = st->time_base;
  159. }
  160. if (sp->first_ts == AV_NOPTS_VALUE) {
  161. // Note down termination timestamp for the next iteration - when
  162. // we encounter a packet with the same timestamp, we will ignore
  163. // any further packets for this stream in next iteration (as they
  164. // are already evaluated).
  165. sp->first_ts = ts;
  166. sp->first_ts_tb = ts_tb;
  167. }
  168. if (sp->term_ts != AV_NOPTS_VALUE &&
  169. av_compare_ts(ts, ts_tb, sp->term_ts, sp->term_ts_tb) > 0) {
  170. // past the end position from last iteration, ignore packet
  171. if (!sp->terminated) {
  172. sp->terminated = 1;
  173. ++terminated_count;
  174. if (sp->pos_hi == INT64_MAX) {
  175. // no high frame exists for this stream
  176. (*found_hi)++;
  177. sp->ts_hi = INT64_MAX;
  178. sp->pos_hi = INT64_MAX - 1;
  179. }
  180. if (terminated_count == keyframes_to_find)
  181. break; // all terminated, iteration done
  182. }
  183. continue;
  184. }
  185. if (av_compare_ts(ts, ts_tb, timestamp, timebase) <= 0) {
  186. // keyframe found before target timestamp
  187. if (sp->pos_lo == INT64_MAX) {
  188. // found first keyframe lower than target timestamp
  189. (*found_lo)++;
  190. sp->ts_lo = ts;
  191. sp->pos_lo = pos;
  192. } else if (sp->ts_lo < ts) {
  193. // found a better match (closer to target timestamp)
  194. sp->ts_lo = ts;
  195. sp->pos_lo = pos;
  196. }
  197. }
  198. if (av_compare_ts(ts, ts_tb, timestamp, timebase) >= 0) {
  199. // keyframe found after target timestamp
  200. if (sp->pos_hi == INT64_MAX) {
  201. // found first keyframe higher than target timestamp
  202. (*found_hi)++;
  203. sp->ts_hi = ts;
  204. sp->pos_hi = pos;
  205. if (*found_hi >= keyframes_to_find && first_iter) {
  206. // We found high frame for all. They may get updated
  207. // to TS closer to target TS in later iterations (which
  208. // will stop at start position of previous iteration).
  209. break;
  210. }
  211. } else if (sp->ts_hi > ts) {
  212. // found a better match (actually, shouldn't happen)
  213. sp->ts_hi = ts;
  214. sp->pos_hi = pos;
  215. }
  216. }
  217. }
  218. }
  219. // Clean up the parser.
  220. ff_read_frame_flush(s);
  221. }
  222. int64_t ff_gen_syncpoint_search(AVFormatContext *s,
  223. int stream_index,
  224. int64_t pos,
  225. int64_t ts_min,
  226. int64_t ts,
  227. int64_t ts_max,
  228. int flags)
  229. {
  230. AVSyncPoint *sync, *sp;
  231. AVStream *st;
  232. int i;
  233. int keyframes_to_find = 0;
  234. int64_t curpos;
  235. int64_t step;
  236. int found_lo = 0, found_hi = 0;
  237. int64_t min_distance, distance;
  238. int64_t min_pos = 0;
  239. int first_iter = 1;
  240. AVRational time_base;
  241. if (flags & AVSEEK_FLAG_BYTE) {
  242. // for byte seeking, we have exact 1:1 "timestamps" - positions
  243. time_base.num = 1;
  244. time_base.den = 1;
  245. } else {
  246. if (stream_index >= 0) {
  247. // we have a reference stream, which time base we use
  248. st = s->streams[stream_index];
  249. time_base = st->time_base;
  250. } else {
  251. // no reference stream, use AV_TIME_BASE as reference time base
  252. time_base.num = 1;
  253. time_base.den = AV_TIME_BASE;
  254. }
  255. }
  256. // Initialize syncpoint structures for each stream.
  257. sync = av_malloc(s->nb_streams * sizeof(AVSyncPoint));
  258. if (!sync)
  259. // cannot allocate helper structure
  260. return -1;
  261. for (i = 0; i < s->nb_streams; ++i) {
  262. st = s->streams[i];
  263. sp = &sync[i];
  264. sp->pos_lo = INT64_MAX;
  265. sp->ts_lo = INT64_MAX;
  266. sp->pos_hi = INT64_MAX;
  267. sp->ts_hi = INT64_MAX;
  268. sp->terminated = 0;
  269. sp->first_ts = AV_NOPTS_VALUE;
  270. sp->term_ts = ts_max;
  271. sp->term_ts_tb = time_base;
  272. sp->last_pos = pos;
  273. st->cur_dts = AV_NOPTS_VALUE;
  274. if (st->discard < AVDISCARD_ALL)
  275. ++keyframes_to_find;
  276. }
  277. if (!keyframes_to_find) {
  278. // no stream active, error
  279. av_free(sync);
  280. return -1;
  281. }
  282. // Find keyframes in all active streams with timestamp/position just before
  283. // and just after requested timestamp/position.
  284. step = s->pb->buffer_size;
  285. curpos = FFMAX(pos - step / 2, 0);
  286. for (;;) {
  287. avio_seek(s->pb, curpos, SEEK_SET);
  288. search_hi_lo_keyframes(s,
  289. ts, time_base,
  290. flags,
  291. sync,
  292. keyframes_to_find,
  293. &found_lo, &found_hi,
  294. first_iter);
  295. if (found_lo == keyframes_to_find && found_hi == keyframes_to_find)
  296. break; // have all keyframes we wanted
  297. if (!curpos)
  298. break; // cannot go back anymore
  299. curpos = pos - step;
  300. if (curpos < 0)
  301. curpos = 0;
  302. step *= 2;
  303. // switch termination positions
  304. for (i = 0; i < s->nb_streams; ++i) {
  305. st = s->streams[i];
  306. st->cur_dts = AV_NOPTS_VALUE;
  307. sp = &sync[i];
  308. if (sp->first_ts != AV_NOPTS_VALUE) {
  309. sp->term_ts = sp->first_ts;
  310. sp->term_ts_tb = sp->first_ts_tb;
  311. sp->first_ts = AV_NOPTS_VALUE;
  312. }
  313. sp->terminated = 0;
  314. sp->last_pos = curpos;
  315. }
  316. first_iter = 0;
  317. }
  318. // Find actual position to start decoding so that decoder synchronizes
  319. // closest to ts and between ts_min and ts_max.
  320. pos = INT64_MAX;
  321. for (i = 0; i < s->nb_streams; ++i) {
  322. st = s->streams[i];
  323. if (st->discard < AVDISCARD_ALL) {
  324. sp = &sync[i];
  325. min_distance = INT64_MAX;
  326. // Find timestamp closest to requested timestamp within min/max limits.
  327. if (sp->pos_lo != INT64_MAX
  328. && av_compare_ts(ts_min, time_base, sp->ts_lo, st->time_base) <= 0
  329. && av_compare_ts(sp->ts_lo, st->time_base, ts_max, time_base) <= 0) {
  330. // low timestamp is in range
  331. min_distance = ts_distance(ts, time_base, sp->ts_lo, st->time_base);
  332. min_pos = sp->pos_lo;
  333. }
  334. if (sp->pos_hi != INT64_MAX
  335. && av_compare_ts(ts_min, time_base, sp->ts_hi, st->time_base) <= 0
  336. && av_compare_ts(sp->ts_hi, st->time_base, ts_max, time_base) <= 0) {
  337. // high timestamp is in range, check distance
  338. distance = ts_distance(sp->ts_hi, st->time_base, ts, time_base);
  339. if (distance < min_distance) {
  340. min_distance = distance;
  341. min_pos = sp->pos_hi;
  342. }
  343. }
  344. if (min_distance == INT64_MAX) {
  345. // no timestamp is in range, cannot seek
  346. av_free(sync);
  347. return -1;
  348. }
  349. if (min_pos < pos)
  350. pos = min_pos;
  351. }
  352. }
  353. avio_seek(s->pb, pos, SEEK_SET);
  354. av_free(sync);
  355. return pos;
  356. }
  357. AVParserState *ff_store_parser_state(AVFormatContext *s)
  358. {
  359. int i;
  360. AVStream *st;
  361. AVParserStreamState *ss;
  362. AVParserState *state = av_malloc(sizeof(AVParserState));
  363. if (!state)
  364. return NULL;
  365. state->stream_states = av_malloc(sizeof(AVParserStreamState) * s->nb_streams);
  366. if (!state->stream_states) {
  367. av_free(state);
  368. return NULL;
  369. }
  370. state->fpos = avio_tell(s->pb);
  371. // copy context structures
  372. state->packet_buffer = s->packet_buffer;
  373. state->parse_queue = s->parse_queue;
  374. state->raw_packet_buffer = s->raw_packet_buffer;
  375. state->raw_packet_buffer_remaining_size = s->raw_packet_buffer_remaining_size;
  376. s->packet_buffer = NULL;
  377. s->parse_queue = NULL;
  378. s->raw_packet_buffer = NULL;
  379. s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
  380. // copy stream structures
  381. state->nb_streams = s->nb_streams;
  382. for (i = 0; i < s->nb_streams; i++) {
  383. st = s->streams[i];
  384. ss = &state->stream_states[i];
  385. ss->parser = st->parser;
  386. ss->last_IP_pts = st->last_IP_pts;
  387. ss->cur_dts = st->cur_dts;
  388. ss->probe_packets = st->probe_packets;
  389. st->parser = NULL;
  390. st->last_IP_pts = AV_NOPTS_VALUE;
  391. st->cur_dts = AV_NOPTS_VALUE;
  392. st->probe_packets = MAX_PROBE_PACKETS;
  393. }
  394. return state;
  395. }
  396. void ff_restore_parser_state(AVFormatContext *s, AVParserState *state)
  397. {
  398. int i;
  399. AVStream *st;
  400. AVParserStreamState *ss;
  401. ff_read_frame_flush(s);
  402. if (!state)
  403. return;
  404. avio_seek(s->pb, state->fpos, SEEK_SET);
  405. // copy context structures
  406. s->packet_buffer = state->packet_buffer;
  407. s->parse_queue = state->parse_queue;
  408. s->raw_packet_buffer = state->raw_packet_buffer;
  409. s->raw_packet_buffer_remaining_size = state->raw_packet_buffer_remaining_size;
  410. // copy stream structures
  411. for (i = 0; i < state->nb_streams; i++) {
  412. st = s->streams[i];
  413. ss = &state->stream_states[i];
  414. st->parser = ss->parser;
  415. st->last_IP_pts = ss->last_IP_pts;
  416. st->cur_dts = ss->cur_dts;
  417. st->probe_packets = ss->probe_packets;
  418. }
  419. av_free(state->stream_states);
  420. av_free(state);
  421. }
  422. static void free_packet_list(AVPacketList *pktl)
  423. {
  424. AVPacketList *cur;
  425. while (pktl) {
  426. cur = pktl;
  427. pktl = cur->next;
  428. av_free_packet(&cur->pkt);
  429. av_free(cur);
  430. }
  431. }
  432. void ff_free_parser_state(AVFormatContext *s, AVParserState *state)
  433. {
  434. int i;
  435. AVParserStreamState *ss;
  436. if (!state)
  437. return;
  438. for (i = 0; i < state->nb_streams; i++) {
  439. ss = &state->stream_states[i];
  440. if (ss->parser)
  441. av_parser_close(ss->parser);
  442. }
  443. free_packet_list(state->packet_buffer);
  444. free_packet_list(state->parse_queue);
  445. free_packet_list(state->raw_packet_buffer);
  446. av_free(state->stream_states);
  447. av_free(state);
  448. }