// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/formats/webcodecs/webcodecs_encoded_chunk_stream_parser.h"

#include <string>

#include "base/callback.h"
#include "base/logging.h"
#include "base/notreached.h"
#include "media/base/media_log.h"
#include "media/base/media_track.h"
#include "media/base/media_tracks.h"
#include "media/base/stream_parser_buffer.h"
#include "media/base/text_track_config.h"
#include "media/base/timestamp_constants.h"

namespace {

// TODO(crbug.com/1144908): Since these must be identical to those generated
// in the SourceBuffer, consider moving these to possibly stream_parser.h.
// Meanwhile, must be kept in sync with similar constexpr in SourceBuffer
// manually.
constexpr media::StreamParser::TrackId kWebCodecsAudioTrackId = 1;
constexpr media::StreamParser::TrackId kWebCodecsVideoTrackId = 2;

}  // namespace

namespace media {

WebCodecsEncodedChunkStreamParser::WebCodecsEncodedChunkStreamParser(
    std::unique_ptr<AudioDecoderConfig> audio_config)
    : state_(kWaitingForInit), audio_config_(std::move(audio_config)) {
  DCHECK(audio_config_ && !video_config_);
}

WebCodecsEncodedChunkStreamParser::WebCodecsEncodedChunkStreamParser(
    std::unique_ptr<VideoDecoderConfig> video_config)
    : state_(kWaitingForInit), video_config_(std::move(video_config)) {
  DCHECK(video_config_ && !audio_config_);
}

WebCodecsEncodedChunkStreamParser::~WebCodecsEncodedChunkStreamParser() =
    default;

void WebCodecsEncodedChunkStreamParser::Init(
    InitCB init_cb,
    const NewConfigCB& config_cb,
    const NewBuffersCB& new_buffers_cb,
    bool /* ignore_text_tracks */,
    const EncryptedMediaInitDataCB& /* ignored */,
    const NewMediaSegmentCB& new_segment_cb,
    const EndMediaSegmentCB& end_of_segment_cb,
    MediaLog* media_log) {
  DCHECK_EQ(state_, kWaitingForInit);
  DCHECK(!init_cb_);
  DCHECK(init_cb);
  DCHECK(config_cb);
  DCHECK(new_buffers_cb);
  DCHECK(new_segment_cb);
  DCHECK(end_of_segment_cb);

  ChangeState(kWaitingForConfigEmission);
  init_cb_ = std::move(init_cb);
  config_cb_ = config_cb;
  new_buffers_cb_ = new_buffers_cb;
  new_segment_cb_ = new_segment_cb;
  end_of_segment_cb_ = end_of_segment_cb;
  media_log_ = media_log;
}

void WebCodecsEncodedChunkStreamParser::Flush() {
  DCHECK_NE(state_, kWaitingForInit);
  if (state_ == kWaitingForEncodedChunks)
    ChangeState(kWaitingForConfigEmission);
}

bool WebCodecsEncodedChunkStreamParser::GetGenerateTimestampsFlag() const {
  return false;
}

bool WebCodecsEncodedChunkStreamParser::Parse(const uint8_t* /* buf */,
                                              int /* size */) {
  // TODO(crbug.com/1144908): Protect against app reaching this (and similer
  // inverse case in other parsers) simply by using the wrong append method on
  // the SourceBuffer. Maybe a better MEDIA_LOG here would be sufficient?  Or
  // instead have the top-level SourceBuffer throw synchronous exception when
  // attempting the wrong append method, without causing parse/decode error?
  NOTREACHED();  // ProcessChunks() is the method to use instead for this
                 // parser.
  return false;
}

bool WebCodecsEncodedChunkStreamParser::ProcessChunks(
    std::unique_ptr<BufferQueue> buffer_queue) {
  DCHECK_NE(state_, kWaitingForInit);

  if (state_ == kError)
    return false;

  if (state_ == kWaitingForConfigEmission) {
    // Must (still) have only one config. We'll retain ownership.
    // MediaTracks::AddAudio/VideoTrack copies the config.
    DCHECK((audio_config_ && !video_config_) ||
           (video_config_ && !audio_config_));
    auto media_tracks = std::make_unique<MediaTracks>();
    if (audio_config_) {
      media_tracks->AddAudioTrack(
          *audio_config_, kWebCodecsAudioTrackId, MediaTrack::Kind("main"),
          MediaTrack::Label(""), MediaTrack::Language(""));
    } else if (video_config_) {
      media_tracks->AddVideoTrack(
          *video_config_, kWebCodecsVideoTrackId, MediaTrack::Kind("main"),
          MediaTrack::Label(""), MediaTrack::Language(""));
    }

    if (!config_cb_.Run(std::move(media_tracks), TextTrackConfigMap())) {
      ChangeState(kError);
      return false;
    }

    if (init_cb_) {
      InitParameters params(kInfiniteDuration);
      params.liveness = DemuxerStream::LIVENESS_UNKNOWN;
      if (audio_config_)
        params.detected_audio_track_count = 1;
      if (video_config_)
        params.detected_video_track_count = 1;
      params.detected_text_track_count = 0;
      std::move(init_cb_).Run(params);
    }

    ChangeState(kWaitingForEncodedChunks);
  }

  DCHECK_EQ(state_, kWaitingForEncodedChunks);

  // All of |buffer_queue| must be of the media type (audio or video)
  // corresponding to the exactly one type of decoder config we have. Otherwise,
  // the caller has provided encoded chunks for the wrong kind of config.
  DemuxerStream::Type expected_type =
      audio_config_ ? DemuxerStream::AUDIO : DemuxerStream::VIDEO;
  for (const auto& it : *buffer_queue) {
    if (it->type() != expected_type) {
      MEDIA_LOG(ERROR, media_log_)
          << "Incorrect EncodedChunk type (audio vs video) appended";
      ChangeState(kError);
      return false;
    }
  }

  // TODO(crbug.com/1144908): Add a different new_buffers_cb type for us to use
  // so that we can just std::move the buffer_queue, and avoid potential issues
  // with out-of-order timestamps in the caller-provided queue that would
  // otherwise cause parse failure in MergeBufferQueues with the current, legacy
  // style of new_buffers_cb that depends on parsers to emit sanely time-ordered
  // groups of frames from *muxed* multi-track bytestreams. FrameProcessor is
  // capable of handling our buffer_queue verbatim.
  BufferQueueMap buffers;
  if (audio_config_)
    buffers.insert(std::make_pair(kWebCodecsAudioTrackId, *buffer_queue));
  else
    buffers.insert(std::make_pair(kWebCodecsVideoTrackId, *buffer_queue));
  new_segment_cb_.Run();
  if (!new_buffers_cb_.Run(buffers))
    return false;
  end_of_segment_cb_.Run();

  return true;
}

void WebCodecsEncodedChunkStreamParser::ChangeState(State new_state) {
  DVLOG(1) << __func__ << ": " << state_ << " -> " << new_state;
  state_ = new_state;
}

}  // namespace media
