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.

579 lines
20KB

  1. /*
  2. * Utility functions for seeking for use within FFmpeg 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 "seek.h"
  23. #include "libavutil/mem.h"
  24. // NOTE: implementation should be moved here in another patch, to keep patches
  25. // separated.
  26. extern void av_read_frame_flush(AVFormatContext *s);
  27. /**
  28. * Helper structure to store parser state of AVStream.
  29. */
  30. typedef struct AVStreamState {
  31. // Saved members of AVStream
  32. AVCodecParserContext *parser;
  33. AVPacket cur_pkt;
  34. int64_t last_IP_pts;
  35. int64_t cur_dts;
  36. int64_t reference_dts;
  37. const uint8_t *cur_ptr;
  38. int cur_len;
  39. int probe_packets;
  40. } AVStreamState;
  41. /**
  42. * Helper structure to store parser state of AVFormat.
  43. */
  44. struct AVParserState {
  45. int64_t fpos; ///< File position at the time of call.
  46. // Saved members of AVFormatContext
  47. AVStream *cur_st; ///< Current stream.
  48. AVPacketList *packet_buffer; ///< Packet buffer of original state.
  49. AVPacketList *raw_packet_buffer; ///< Raw packet buffer of original state.
  50. int raw_packet_buffer_remaining_size; ///< Remaining size available for raw_packet_buffer.
  51. // Saved info for streams.
  52. int nb_streams; ///< Number of streams with stored state.
  53. AVStreamState *stream_states; ///< States of individual streams (array).
  54. };
  55. /**
  56. * Helper structure describing keyframe search state of one stream.
  57. */
  58. typedef struct {
  59. int64_t pos_lo; ///< Position of the frame with low timestamp in file or INT64_MAX if not found (yet).
  60. int64_t ts_lo; ///< Frame presentation timestamp or same as pos_lo for byte seeking.
  61. int64_t pos_hi; ///< Position of the frame with high timestamp in file or INT64_MAX if not found (yet).
  62. int64_t ts_hi; ///< Frame presentation timestamp or same as pos_hi for byte seeking.
  63. int64_t last_pos; ///< Last known position of a frame, for multi-frame packets.
  64. int64_t term_ts; ///< Termination timestamp (which TS we already read).
  65. AVRational term_ts_tb; ///< Timebase for term_ts.
  66. int64_t first_ts; ///< First packet timestamp in this iteration (to fill term_ts later).
  67. AVRational first_ts_tb;///< Timebase for first_ts.
  68. int terminated; ///< Termination flag for current iteration.
  69. } AVSyncPoint;
  70. /**
  71. * Compare two timestamps exactly, taking into account their respective time bases.
  72. *
  73. * @param ts_a timestamp A.
  74. * @param tb_a time base for timestamp A.
  75. * @param ts_b timestamp B.
  76. * @param tb_b time base for timestamp A.
  77. * @return -1. 0 or 1 if timestamp A is less than, equal or greater than timestamp B.
  78. */
  79. static int compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b)
  80. {
  81. int64_t a, b, res;
  82. if (ts_a == INT64_MIN)
  83. return ts_a < ts_b ? -1 : 0;
  84. if (ts_a == INT64_MAX)
  85. return ts_a > ts_b ? 1 : 0;
  86. if (ts_b == INT64_MIN)
  87. return ts_a > ts_b ? 1 : 0;
  88. if (ts_b == INT64_MAX)
  89. return ts_a < ts_b ? -1 : 0;
  90. a = ts_a * tb_a.num * tb_b.den;
  91. b = ts_b * tb_b.num * tb_a.den;
  92. res = a - b;
  93. if (res == 0)
  94. return 0;
  95. else
  96. return (res >> 63) | 1;
  97. }
  98. /**
  99. * Compute a distance between timestamps.
  100. *
  101. * Distances are only comparable, if same time bases are used for computing
  102. * distances.
  103. *
  104. * @param ts_hi high timestamp.
  105. * @param tb_hi high timestamp time base.
  106. * @param ts_lo low timestamp.
  107. * @param tb_lo low timestamp time base.
  108. * @return representation of distance between high and low timestamps.
  109. */
  110. static int64_t ts_distance(int64_t ts_hi, AVRational tb_hi, int64_t ts_lo, AVRational tb_lo)
  111. {
  112. int64_t hi, lo;
  113. hi = ts_hi * tb_hi.num * tb_lo.den;
  114. lo = ts_lo * tb_lo.num * tb_hi.den;
  115. return hi - lo;
  116. }
  117. /**
  118. * Partial search for keyframes in multiple streams.
  119. *
  120. * This routine searches for the next lower and next higher timestamp to
  121. * given target timestamp in each stream, starting at current file position
  122. * and ending at position, where all streams have already been examined
  123. * (or when all higher key frames found in first iteration).
  124. *
  125. * This routine is called iteratively with exponential backoff to find lower
  126. * timestamp.
  127. *
  128. * @param s format context.
  129. * @param timestamp target timestamp (or position, if AVSEEK_FLAG_BYTE).
  130. * @param timebase time base for timestamps.
  131. * @param flags seeking flags.
  132. * @param sync array with information per stream.
  133. * @param keyframes_to_find count of keyframes to find in total.
  134. * @param found_lo pointer to count of already found low timestamp keyframes.
  135. * @param found_hi pointer to count of already found high timestamp keyframes.
  136. * @param first_iter flag for first iteration.
  137. */
  138. static void search_hi_lo_keyframes(AVFormatContext *s,
  139. int64_t timestamp,
  140. AVRational timebase,
  141. int flags,
  142. AVSyncPoint *sync,
  143. int keyframes_to_find,
  144. int *found_lo,
  145. int *found_hi,
  146. int first_iter)
  147. {
  148. AVPacket pkt;
  149. AVSyncPoint *sp;
  150. AVStream *st;
  151. int idx;
  152. int flg;
  153. int terminated_count = 0;
  154. int64_t pos;
  155. int64_t pts, dts; // PTS/DTS from stream
  156. int64_t ts; // PTS in stream-local time base or position for byte seeking
  157. AVRational ts_tb; // Time base of the stream or 1:1 for byte seeking
  158. for (;;) {
  159. if (av_read_frame(s, &pkt) < 0) {
  160. // EOF or error, make sure high flags are set
  161. for (idx = 0; idx < s->nb_streams; ++idx) {
  162. if (s->streams[idx]->discard < AVDISCARD_ALL) {
  163. sp = &sync[idx];
  164. if (sp->pos_hi == INT64_MAX) {
  165. // No high frame exists for this stream
  166. (*found_hi)++;
  167. sp->ts_hi = INT64_MAX;
  168. sp->pos_hi = INT64_MAX - 1;
  169. }
  170. }
  171. }
  172. break;
  173. }
  174. idx = pkt.stream_index;
  175. st = s->streams[idx];
  176. if (st->discard >= AVDISCARD_ALL) {
  177. // This stream is not active, skip packet.
  178. continue;
  179. }
  180. sp = &sync[idx];
  181. flg = pkt.flags;
  182. pos = pkt.pos;
  183. pts = pkt.pts;
  184. dts = pkt.dts;
  185. if (pts == AV_NOPTS_VALUE) {
  186. // Some formats don't provide PTS, only DTS.
  187. pts = dts;
  188. }
  189. av_free_packet(&pkt);
  190. // Multi-frame packets only return position for the very first frame.
  191. // Other frames are read with position == -1. Therefore, we note down
  192. // last known position of a frame and use it if a frame without
  193. // position arrives. In this way, it's possible to seek to proper
  194. // position. Additionally, for parsers not providing position at all,
  195. // an approximation will be used (starting position of this iteration).
  196. if (pos < 0) {
  197. pos = sp->last_pos;
  198. } else {
  199. sp->last_pos = pos;
  200. }
  201. // Evaluate key frames with known TS (or any frames, if AVSEEK_FLAG_ANY set).
  202. if (pts != AV_NOPTS_VALUE && ((flg & PKT_FLAG_KEY) || (flags & AVSEEK_FLAG_ANY))) {
  203. if (flags & AVSEEK_FLAG_BYTE) {
  204. // For byte seeking, use position as timestamp.
  205. ts = pos;
  206. ts_tb.num = 1;
  207. ts_tb.den = 1;
  208. } else {
  209. // Get stream time_base.
  210. ts = pts;
  211. ts_tb = st->time_base;
  212. }
  213. if (sp->first_ts == AV_NOPTS_VALUE) {
  214. // Note down termination timestamp for the next iteration - when
  215. // we encounter a packet with the same timestamp, we will ignore
  216. // any further packets for this stream in next iteration (as they
  217. // are already evaluated).
  218. sp->first_ts = ts;
  219. sp->first_ts_tb = ts_tb;
  220. }
  221. if (sp->term_ts != AV_NOPTS_VALUE && compare_ts(ts, ts_tb, sp->term_ts, sp->term_ts_tb) > 0) {
  222. // We are past the end position from last iteration, ignore packet.
  223. if (!sp->terminated) {
  224. sp->terminated = 1;
  225. ++terminated_count;
  226. if (sp->pos_hi == INT64_MAX) {
  227. // No high frame exists for this stream
  228. (*found_hi)++;
  229. sp->ts_hi = INT64_MAX;
  230. sp->pos_hi = INT64_MAX - 1;
  231. }
  232. if (terminated_count == keyframes_to_find)
  233. break; // all terminated, iteration done
  234. }
  235. continue;
  236. }
  237. if (compare_ts(ts, ts_tb, timestamp, timebase) <= 0) {
  238. // Keyframe found before target timestamp.
  239. if (sp->pos_lo == INT64_MAX) {
  240. // Found first keyframe lower than target timestamp.
  241. (*found_lo)++;
  242. sp->ts_lo = ts;
  243. sp->pos_lo = pos;
  244. } else if (sp->ts_lo < ts) {
  245. // Found a better match (closer to target timestamp).
  246. sp->ts_lo = ts;
  247. sp->pos_lo = pos;
  248. }
  249. }
  250. if (compare_ts(ts, ts_tb, timestamp, timebase) >= 0) {
  251. // Keyframe found after target timestamp.
  252. if (sp->pos_hi == INT64_MAX) {
  253. // Found first keyframe higher than target timestamp.
  254. (*found_hi)++;
  255. sp->ts_hi = ts;
  256. sp->pos_hi = pos;
  257. if (*found_hi >= keyframes_to_find && first_iter) {
  258. // We found high frame for all. They may get updated
  259. // to TS closer to target TS in later iterations (which
  260. // will stop at start position of previous iteration).
  261. break;
  262. }
  263. } else if (sp->ts_hi > ts) {
  264. // Found a better match (actually, shouldn't happen).
  265. sp->ts_hi = ts;
  266. sp->pos_hi = pos;
  267. }
  268. }
  269. }
  270. }
  271. // Clean up the parser.
  272. av_read_frame_flush(s);
  273. }
  274. int64_t ff_gen_syncpoint_search(AVFormatContext *s,
  275. int stream_index,
  276. int64_t pos,
  277. int64_t ts_min,
  278. int64_t ts,
  279. int64_t ts_max,
  280. int flags)
  281. {
  282. AVSyncPoint *sync, *sp;
  283. AVStream *st;
  284. int i;
  285. int keyframes_to_find = 0;
  286. int64_t curpos;
  287. int64_t step;
  288. int found_lo = 0, found_hi = 0;
  289. int64_t min_distance, distance;
  290. int64_t min_pos = 0;
  291. int first_iter = 1;
  292. AVRational time_base;
  293. if (flags & AVSEEK_FLAG_BYTE) {
  294. /* For byte seeking, we have exact 1:1 "timestamps" - positions */
  295. time_base.num = 1;
  296. time_base.den = 1;
  297. } else {
  298. if (stream_index >= 0) {
  299. /* We have a reference stream, which time base we use */
  300. st = s->streams[stream_index];
  301. time_base = st->time_base;
  302. } else {
  303. /* No reference stream, use AV_TIME_BASE as reference time base */
  304. time_base.num = 1;
  305. time_base.den = AV_TIME_BASE;
  306. }
  307. }
  308. // Initialize syncpoint structures for each stream.
  309. sync = (AVSyncPoint*) av_malloc(s->nb_streams * sizeof(AVSyncPoint));
  310. if (!sync) {
  311. // cannot allocate helper structure
  312. return -1;
  313. }
  314. for (i = 0; i < s->nb_streams; ++i) {
  315. st = s->streams[i];
  316. sp = &sync[i];
  317. sp->pos_lo = INT64_MAX;
  318. sp->ts_lo = INT64_MAX;
  319. sp->pos_hi = INT64_MAX;
  320. sp->ts_hi = INT64_MAX;
  321. sp->terminated = 0;
  322. sp->first_ts = AV_NOPTS_VALUE;
  323. sp->term_ts = ts_max;
  324. sp->term_ts_tb = time_base;
  325. sp->last_pos = pos;
  326. st->cur_dts = AV_NOPTS_VALUE;
  327. if (st->discard < AVDISCARD_ALL)
  328. ++keyframes_to_find;
  329. }
  330. if (keyframes_to_find == 0) {
  331. // No stream active, error.
  332. av_free(sync);
  333. return -1;
  334. }
  335. // Find keyframes in all active streams with timestamp/position just before
  336. // and just after requested timestamp/position.
  337. step = 1024;
  338. curpos = pos;
  339. for (;;) {
  340. url_fseek(s->pb, curpos, SEEK_SET);
  341. search_hi_lo_keyframes(s,
  342. ts, time_base,
  343. flags,
  344. sync,
  345. keyframes_to_find,
  346. &found_lo, &found_hi,
  347. first_iter);
  348. if (found_lo == keyframes_to_find && found_hi == keyframes_to_find)
  349. break; // have all keyframes we wanted
  350. if (curpos == 0)
  351. break; // cannot go back anymore
  352. curpos = pos - step;
  353. if (curpos < 0)
  354. curpos = 0;
  355. step *= 2;
  356. // switch termination positions
  357. for (i = 0; i < s->nb_streams; ++i) {
  358. st = s->streams[i];
  359. st->cur_dts = AV_NOPTS_VALUE;
  360. sp = &sync[i];
  361. if (sp->first_ts != AV_NOPTS_VALUE) {
  362. sp->term_ts = sp->first_ts;
  363. sp->term_ts_tb = sp->first_ts_tb;
  364. sp->first_ts = AV_NOPTS_VALUE;
  365. }
  366. sp->terminated = 0;
  367. sp->last_pos = curpos;
  368. }
  369. first_iter = 0;
  370. }
  371. // Find actual position to start decoding so that decoder synchronizes
  372. // closest to ts and between ts_min and ts_max.
  373. pos = INT64_MAX;
  374. for (i = 0; i < s->nb_streams; ++i) {
  375. st = s->streams[i];
  376. if (st->discard < AVDISCARD_ALL) {
  377. sp = &sync[i];
  378. min_distance = INT64_MAX;
  379. // Find timestamp closest to requested timestamp within min/max limits.
  380. if (sp->pos_lo != INT64_MAX
  381. && compare_ts(ts_min, time_base, sp->ts_lo, st->time_base) <= 0
  382. && compare_ts(sp->ts_lo, st->time_base, ts_max, time_base) <= 0) {
  383. // low timestamp is in range
  384. min_distance = ts_distance(ts, time_base, sp->ts_lo, st->time_base);
  385. min_pos = sp->pos_lo;
  386. }
  387. if (sp->pos_hi != INT64_MAX
  388. && compare_ts(ts_min, time_base, sp->ts_hi, st->time_base) <= 0
  389. && compare_ts(sp->ts_hi, st->time_base, ts_max, time_base) <= 0) {
  390. // high timestamp is in range, check distance
  391. distance = ts_distance(sp->ts_hi, st->time_base, ts, time_base);
  392. if (distance < min_distance) {
  393. min_distance = distance;
  394. min_pos = sp->pos_hi;
  395. }
  396. }
  397. if (min_distance == INT64_MAX) {
  398. // no timestamp is in range, cannot seek
  399. av_free(sync);
  400. return -1;
  401. }
  402. if (min_pos < pos)
  403. pos = min_pos;
  404. }
  405. }
  406. url_fseek(s->pb, pos, SEEK_SET);
  407. av_free(sync);
  408. return pos;
  409. }
  410. AVParserState *ff_store_parser_state(AVFormatContext *s)
  411. {
  412. int i;
  413. AVStream *st;
  414. AVStreamState *ss;
  415. AVParserState *state = (AVParserState*) av_malloc(sizeof(AVParserState));
  416. if (!state)
  417. return NULL;
  418. state->stream_states = (AVStreamState*) av_malloc(sizeof(AVStreamState) * s->nb_streams);
  419. if (!state->stream_states) {
  420. av_free(state);
  421. return NULL;
  422. }
  423. state->fpos = url_ftell(s->pb);
  424. // copy context structures
  425. state->cur_st = s->cur_st;
  426. state->packet_buffer = s->packet_buffer;
  427. state->raw_packet_buffer = s->raw_packet_buffer;
  428. state->raw_packet_buffer_remaining_size = s->raw_packet_buffer_remaining_size;
  429. s->cur_st = NULL;
  430. s->packet_buffer = NULL;
  431. s->raw_packet_buffer = NULL;
  432. s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
  433. // copy stream structures
  434. state->nb_streams = s->nb_streams;
  435. for (i = 0; i < s->nb_streams; i++) {
  436. st = s->streams[i];
  437. ss = &state->stream_states[i];
  438. ss->parser = st->parser;
  439. ss->last_IP_pts = st->last_IP_pts;
  440. ss->cur_dts = st->cur_dts;
  441. ss->reference_dts = st->reference_dts;
  442. ss->cur_ptr = st->cur_ptr;
  443. ss->cur_len = st->cur_len;
  444. ss->probe_packets = st->probe_packets;
  445. ss->cur_pkt = st->cur_pkt;
  446. st->parser = NULL;
  447. st->last_IP_pts = AV_NOPTS_VALUE;
  448. st->cur_dts = AV_NOPTS_VALUE;
  449. st->reference_dts = AV_NOPTS_VALUE;
  450. st->cur_ptr = NULL;
  451. st->cur_len = 0;
  452. st->probe_packets = MAX_PROBE_PACKETS;
  453. av_init_packet(&st->cur_pkt);
  454. }
  455. return state;
  456. }
  457. void ff_restore_parser_state(AVFormatContext *s, AVParserState *state)
  458. {
  459. int i;
  460. AVStream *st;
  461. AVStreamState *ss;
  462. av_read_frame_flush(s);
  463. if (!state)
  464. return;
  465. url_fseek(s->pb, state->fpos, SEEK_SET);
  466. // copy context structures
  467. s->cur_st = state->cur_st;
  468. s->packet_buffer = state->packet_buffer;
  469. s->raw_packet_buffer = state->raw_packet_buffer;
  470. s->raw_packet_buffer_remaining_size = state->raw_packet_buffer_remaining_size;
  471. // copy stream structures
  472. for (i = 0; i < state->nb_streams; i++) {
  473. st = s->streams[i];
  474. ss = &state->stream_states[i];
  475. st->parser = ss->parser;
  476. st->last_IP_pts = ss->last_IP_pts;
  477. st->cur_dts = ss->cur_dts;
  478. st->reference_dts = ss->reference_dts;
  479. st->cur_ptr = ss->cur_ptr;
  480. st->cur_len = ss->cur_len;
  481. st->probe_packets = ss->probe_packets;
  482. st->cur_pkt = ss->cur_pkt;
  483. }
  484. av_free(state->stream_states);
  485. av_free(state);
  486. }
  487. static void free_packet_list(AVPacketList *pktl)
  488. {
  489. AVPacketList *cur;
  490. while (pktl) {
  491. cur = pktl;
  492. pktl = cur->next;
  493. av_free_packet(&cur->pkt);
  494. av_free(cur);
  495. }
  496. }
  497. void ff_free_parser_state(AVFormatContext *s, AVParserState *state)
  498. {
  499. int i;
  500. AVStreamState *ss;
  501. if (!state)
  502. return;
  503. for (i = 0; i < state->nb_streams; i++) {
  504. ss = &state->stream_states[i];
  505. if (ss->parser)
  506. av_parser_close(ss->parser);
  507. av_free_packet(&ss->cur_pkt);
  508. }
  509. free_packet_list(state->packet_buffer);
  510. free_packet_list(state->raw_packet_buffer);
  511. av_free(state->stream_states);
  512. av_free(state);
  513. }