blob: ba9e17d9eea47d37fd0fe8a089b958a48eac5df8 [file] [log] [blame]
/*
* Copyright 2014 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MEDIA_FILTERS_SHELL_VIDEO_DECODER_IMPL_H_
#define MEDIA_FILTERS_SHELL_VIDEO_DECODER_IMPL_H_
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/threading/thread.h"
#include "media/base/demuxer_stream.h"
#include "media/base/shell_buffer_factory.h"
#include "media/base/video_decoder.h"
#include "media/base/video_decoder_config.h"
namespace media {
class ShellRawVideoDecoder {
public:
enum DecodeStatus {
FRAME_DECODED, // Successfully decoded a frame.
NEED_MORE_DATA, // Need more data to decode the next frame.
RETRY_WITH_SAME_BUFFER, // Retry later with the same input. Note that in
// this case the decoder may still return a valid
// buffered frame.
FATAL_ERROR // Decoder encounters fatal error, abort playback.
};
typedef media::DecoderBuffer DecoderBuffer;
typedef media::VideoDecoderConfig VideoDecoderConfig;
typedef media::VideoFrame VideoFrame;
typedef base::Callback<void(DecodeStatus, const scoped_refptr<VideoFrame>&)>
DecodeCB;
ShellRawVideoDecoder() {}
virtual ~ShellRawVideoDecoder() {}
virtual void Decode(const scoped_refptr<DecoderBuffer>& buffer,
const DecodeCB& decode_cb) = 0;
virtual bool Flush() = 0;
virtual bool UpdateConfig(const VideoDecoderConfig& config) = 0;
// See ShellVideoDecoder for more details about the following two functions.
virtual void NearlyUnderflow() {}
virtual void HaveEnoughFrames() {}
private:
DISALLOW_COPY_AND_ASSIGN(ShellRawVideoDecoder);
};
class ShellRawVideoDecoderFactory {
public:
virtual ~ShellRawVideoDecoderFactory() {}
virtual scoped_ptr<ShellRawVideoDecoder> Create(
const VideoDecoderConfig& config,
Decryptor* decryptor,
bool was_encrypted) = 0;
};
class MEDIA_EXPORT ShellVideoDecoderImpl : public VideoDecoder {
public:
ShellVideoDecoderImpl(
const scoped_refptr<base::MessageLoopProxy>& message_loop,
ShellRawVideoDecoderFactory* raw_video_decoder_factory);
~ShellVideoDecoderImpl() OVERRIDE;
// ShellVideoDecoder implementation.
void Initialize(const scoped_refptr<DemuxerStream>& stream,
const PipelineStatusCB& status_cb,
const StatisticsCB& statistics_cb) OVERRIDE;
void Read(const ReadCB& read_cb) OVERRIDE;
void Reset(const base::Closure& closure) OVERRIDE;
void Stop(const base::Closure& closure) OVERRIDE;
void NearlyUnderflow() OVERRIDE;
void HaveEnoughFrames() OVERRIDE;
private:
enum DecoderState {
kUninitialized,
kNormal,
kFlushCodec,
kDecodeFinished,
kShellDecodeError
};
void BufferReady(DemuxerStream::Status status,
const scoped_refptr<DecoderBuffer>& buffer);
// actually makes the call to the platform decoder to decode
void DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer);
// the callback from the raw decoder indicates an operation has been finished.
void DecodeCallback(ShellRawVideoDecoder::DecodeStatus status,
const scoped_refptr<VideoFrame>& frame);
// Posts a task to read from the demuxer stream.
void ReadFromDemuxerStream();
// Reset decoder and call |reset_cb_|.
void DoReset();
// called on decoder thread, fatal error on decode, we shut down decode
void DecoderFatalError();
DecoderState state_;
scoped_refptr<base::MessageLoopProxy> media_pipeline_message_loop_;
ShellRawVideoDecoderFactory* raw_video_decoder_factory_;
scoped_refptr<DemuxerStream> demuxer_stream_;
ReadCB read_cb_;
base::Closure reset_cb_;
scoped_ptr<ShellRawVideoDecoder> raw_decoder_;
// TODO: ensure the demuxer can handle multiple EOS requests then remove this
// hack.
scoped_refptr<DecoderBuffer> eof_buffer_;
scoped_refptr<DecoderBuffer> buffer_to_decode_;
// All decoding tasks will be performed on this thread's message loop
base::Thread decoder_thread_;
DISALLOW_IMPLICIT_CONSTRUCTORS(ShellVideoDecoderImpl);
};
} // namespace media
#endif // MEDIA_FILTERS_SHELL_VIDEO_DECODER_IMPL_H_