Chromium Code Reviews| Index: media/filters/ffmpeg_demuxer.cc |
| diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc |
| index de1968afc43d200f86f0eeb3791621ce72d54d72..cbee00c65a0ebd4cf05170eae2bc3ade990eab35 100644 |
| --- a/media/filters/ffmpeg_demuxer.cc |
| +++ b/media/filters/ffmpeg_demuxer.cc |
| @@ -14,6 +14,7 @@ |
| #include "base/memory/scoped_ptr.h" |
| #include "base/message_loop/message_loop_proxy.h" |
| #include "base/metrics/sparse_histogram.h" |
| +#include "base/strings/string_number_conversions.h" |
| #include "base/strings/string_util.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/sys_byteorder.h" |
| @@ -34,6 +35,38 @@ |
| namespace media { |
| +static base::Time ExtractTimelineOffset(AVFormatContext* format_context) { |
|
scherkus (not reviewing)
2014/04/15 00:53:40
parsing code without tests makes me nervous
how a
acolwell GONE FROM CHROMIUM
2014/04/16 01:01:08
Done.
|
| + if (strstr(format_context->iformat->name, "webm") || |
| + strstr(format_context->iformat->name, "matroska")) { |
| + const AVDictionaryEntry* entry = |
| + av_dict_get(format_context->metadata, "creation_time", NULL, 0); |
| + |
| + // Convert ffmpeg UTC representation (YYYY-MM-DD HH:MM:SS) to base::Time. |
|
scherkus (not reviewing)
2014/04/15 00:53:40
s/ffmpeg/FFmpeg/
acolwell GONE FROM CHROMIUM
2014/04/16 01:01:08
Done.
|
| + std::vector<std::string> fields; |
| + std::vector<std::string> date_fields; |
| + std::vector<std::string> time_fields; |
| + base::Time::Exploded exploded; |
| + exploded.millisecond = 0; |
| + |
| + // TODO: Update this parsing code when FFmpeg returns sub-second |
|
scherkus (not reviewing)
2014/04/15 00:53:40
TODO(acolwell)?
acolwell GONE FROM CHROMIUM
2014/04/16 01:01:08
Done.
|
| + // information. |
| + if (entry != NULL && entry->value != NULL && |
| + (Tokenize(entry->value, " ", &fields) == 2) && |
| + (Tokenize(fields[0], "-", &date_fields) == 3) && |
| + (Tokenize(fields[1], ":", &time_fields) == 3) && |
| + base::StringToInt(date_fields[0], &exploded.year) && |
| + base::StringToInt(date_fields[1], &exploded.month) && |
| + base::StringToInt(date_fields[2], &exploded.day_of_month) && |
| + base::StringToInt(time_fields[0], &exploded.hour) && |
| + base::StringToInt(time_fields[1], &exploded.minute) && |
| + base::StringToInt(time_fields[2], &exploded.second)) { |
| + return base::Time::FromUTCExploded(exploded); |
| + } |
| + } |
| + |
| + return base::Time(); |
| +} |
| + |
| // |
| // FFmpegDemuxerStream |
| // |
| @@ -486,6 +519,10 @@ base::TimeDelta FFmpegDemuxer::GetStartTime() const { |
| return start_time_; |
| } |
| +base::Time FFmpegDemuxer::GetWallclockTimelineOffset() const { |
| + return wallclock_timeline_offset_; |
| +} |
| + |
| void FFmpegDemuxer::AddTextStreams() { |
| DCHECK(task_runner_->BelongsToCurrentThread()); |
| @@ -674,6 +711,8 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb, |
| if (strcmp(format_context->iformat->name, "avi") == 0) |
| format_context->flags |= AVFMT_FLAG_GENPTS; |
| + wallclock_timeline_offset_ = ExtractTimelineOffset(format_context); |
| + |
| // Good to go: set the duration and bitrate and notify we're done |
| // initializing. |
| host_->SetDuration(max_duration); |