1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef MEDIA_FORMATS_MP2T_ES_ADAPTER_VIDEO_H_
6#define MEDIA_FORMATS_MP2T_ES_ADAPTER_VIDEO_H_
7
8#include <deque>
9#include <list>
10#include <utility>
11
12#include "base/callback.h"
13#include "base/memory/ref_counted.h"
14#include "base/time/time.h"
15#include "media/base/media_export.h"
16#include "media/base/stream_parser_buffer.h"
17
18namespace media {
19
20class VideoDecoderConfig;
21
22namespace mp2t {
23
24// Some constraints of the MSE spec are not necessarily met by video streams
25// inside an Mpeg2 TS stream.
26// The goal of the ES adapter is to modify the incoming buffers to meet these
27// constraints, e.g.
28// - get the frame duration,
29// - replace the leading non-key frames by the first key frame to avoid
30//   creating a hole in the video timeline.
31class MEDIA_EXPORT EsAdapterVideo {
32 public:
33  typedef base::Callback<void(const VideoDecoderConfig&)> NewVideoConfigCB;
34  typedef base::Callback<void(scoped_refptr<StreamParserBuffer>)> EmitBufferCB;
35
36  EsAdapterVideo(
37      const NewVideoConfigCB& new_video_config_cb,
38      const EmitBufferCB& emit_buffer_cb);
39  ~EsAdapterVideo();
40
41  // Force the emission of the pending video buffers.
42  void Flush();
43
44  // Reset the ES adapter to its initial state.
45  void Reset();
46
47  // Provide the configuration that applies to the upcoming video buffers.
48  void OnConfigChanged(const VideoDecoderConfig& video_decoder_config);
49
50  // Provide a new video buffer.
51  void OnNewBuffer(
52      const scoped_refptr<StreamParserBuffer>& stream_parser_buffer);
53
54 private:
55  typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue;
56  typedef std::pair<int64, VideoDecoderConfig> ConfigEntry;
57
58  void ProcessPendingBuffers(bool flush);
59
60  // Return the PTS of the frame that comes just after |current_pts| in
61  // presentation order. Return kNoTimestamp() if not found.
62  base::TimeDelta GetNextFramePts(base::TimeDelta current_pts);
63
64  // Replace the leading non key frames by |stream_parser_buffer|
65  // (this one must be a key frame).
66  void ReplaceDiscardedFrames(
67      const scoped_refptr<StreamParserBuffer>& stream_parser_buffer);
68
69  NewVideoConfigCB new_video_config_cb_;
70  EmitBufferCB emit_buffer_cb_;
71
72  bool has_valid_config_;
73  bool has_valid_frame_;
74
75  // Duration of the last video frame.
76  base::TimeDelta last_frame_duration_;
77
78  // Association between a video config and a buffer index.
79  std::list<ConfigEntry> config_list_;
80
81  // Global index of the first buffer in |buffer_list_|.
82  int64 buffer_index_;
83
84  // List of buffer to be emitted and PTS of frames already emitted.
85  BufferQueue buffer_list_;
86  std::list<base::TimeDelta> emitted_pts_;
87
88  // - Minimum PTS of discarded frames.
89  // - DTS of discarded frames.
90  base::TimeDelta discarded_frames_min_pts_;
91  std::list<DecodeTimestamp> discarded_frames_dts_;
92
93  DISALLOW_COPY_AND_ASSIGN(EsAdapterVideo);
94};
95
96}  // namespace mp2t
97}  // namespace media
98
99#endif  // MEDIA_FORMATS_MP2T_ES_ADAPTER_VIDEO_H_
100