DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs
media_stream.cc
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/base/media_stream.h"
8 
9 #include "packager/base/logging.h"
10 #include "packager/base/strings/stringprintf.h"
11 #include "packager/media/base/demuxer.h"
12 #include "packager/media/base/media_sample.h"
13 #include "packager/media/base/muxer.h"
14 #include "packager/media/base/stream_info.h"
15 
16 namespace edash_packager {
17 namespace media {
18 
19 MediaStream::MediaStream(scoped_refptr<StreamInfo> info, Demuxer* demuxer)
20  : info_(info), demuxer_(demuxer), muxer_(NULL), state_(kIdle) {}
21 
22 MediaStream::~MediaStream() {}
23 
24 Status MediaStream::PullSample(scoped_refptr<MediaSample>* sample) {
25  DCHECK_EQ(state_, kPulling);
26 
27  // Trigger a new parse in demuxer if no more samples.
28  while (samples_.empty()) {
29  Status status = demuxer_->Parse();
30  if (!status.ok())
31  return status;
32  }
33 
34  *sample = samples_.front();
35  samples_.pop_front();
36  return Status::OK;
37 }
38 
39 Status MediaStream::PushSample(const scoped_refptr<MediaSample>& sample) {
40  switch (state_) {
41  case kIdle:
42  case kPulling:
43  samples_.push_back(sample);
44  return Status::OK;
45  case kDisconnected:
46  return Status::OK;
47  case kPushing:
48  return muxer_->AddSample(this, sample);
49  default:
50  NOTREACHED() << "Unexpected State " << state_;
51  return Status::UNKNOWN;
52  }
53 }
54 
56  DCHECK(muxer);
57  DCHECK(!muxer_);
58  state_ = kConnected;
59  muxer_ = muxer;
60 }
61 
62 Status MediaStream::Start(MediaStreamOperation operation) {
63  DCHECK(demuxer_);
64  DCHECK(operation == kPush || operation == kPull);
65 
66  switch (state_) {
67  case kIdle:
68  // Disconnect the stream if it is not connected to a muxer.
69  state_ = kDisconnected;
70  samples_.clear();
71  return Status::OK;
72  case kConnected:
73  state_ = (operation == kPush) ? kPushing : kPulling;
74  if (operation == kPush) {
75  // Push samples in the queue to muxer if there is any.
76  while (!samples_.empty()) {
77  Status status = muxer_->AddSample(this, samples_.front());
78  if (!status.ok())
79  return status;
80  samples_.pop_front();
81  }
82  } else {
83  // We need to disconnect all its peer streams which are not connected
84  // to a muxer.
85  for (size_t i = 0; i < demuxer_->streams().size(); ++i) {
86  Status status = demuxer_->streams()[i]->Start(operation);
87  if (!status.ok())
88  return status;
89  }
90  }
91  return Status::OK;
92  case kPulling:
93  DCHECK(operation == kPull);
94  return Status::OK;
95  default:
96  NOTREACHED() << "Unexpected State " << state_;
97  return Status::UNKNOWN;
98  }
99 }
100 
101 const scoped_refptr<StreamInfo> MediaStream::info() const { return info_; }
102 
103 std::string MediaStream::ToString() const {
104  return base::StringPrintf("state: %d\n samples in the queue: %zu\n %s",
105  state_, samples_.size(), info_->ToString().c_str());
106 }
107 
108 } // namespace media
109 } // namespace edash_packager
Status PullSample(scoped_refptr< MediaSample > *sample)
Pull sample from Demuxer (triggered by Muxer).
Definition: media_stream.cc:24
MediaStream(scoped_refptr< StreamInfo > info, Demuxer *demuxer)
Definition: media_stream.cc:19
Status Start(MediaStreamOperation operation)
Start the stream for pushing or pulling.
Definition: media_stream.cc:62
const std::vector< MediaStream * > & streams()
Definition: demuxer.h:66
Status PushSample(const scoped_refptr< MediaSample > &sample)
Push sample to Muxer (triggered by Demuxer).
Definition: media_stream.cc:39
Status Parse()
Read from the source and send it to the parser.
Definition: demuxer.cc:166