Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(136)

Side by Side Diff: media/base/media_file_checker.cc

Issue 20572004: Add media file validation to utility process (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nits Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 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 #include "media/base/media_file_checker.h"
6
7 #include <map>
8
9 #include "base/bind.h"
10 #include "base/stl_util.h"
11 #include "base/time/time.h"
12 #include "media/ffmpeg/ffmpeg_common.h"
13 #include "media/filters/blocking_url_protocol.h"
14 #include "media/filters/ffmpeg_glue.h"
15 #include "media/filters/file_data_source.h"
16
17 namespace media {
18
19 namespace {
20
21 const int64 kMaxCheckTimeIneconds = 5;
DaleCurtis 2013/08/08 21:04:33 InSeconds
vandebo (ex-Chrome) 2013/08/08 23:04:18 Done.
22
23 void OnError(bool* called) {
24 *called = false;
25 }
26
27 struct StreamContext {
28 StreamContext()
29 : codec_context(NULL),
30 codec(NULL) {
31 }
32 AVCodecContext* codec_context;
33 AVCodec* codec;
34 };
35
36 } // namespace
37
38
39 MediaFileChecker::MediaFileChecker(base::PlatformFile file)
40 : file_(file),
41 file_closer_(&file_) {
42 }
43
44 MediaFileChecker::~MediaFileChecker() {
45 }
46
47 bool MediaFileChecker::Start(const base::TimeDelta& check_time) {
48 media::FileDataSource source;
49 bool read_ok = true;
50 media::BlockingUrlProtocol protocol(&source, base::Bind(&OnError, &read_ok));
51 media::FFmpegGlue glue(&protocol);
52 source.InitializeFromPlatformFile(file_);
53 AVFormatContext* format_context = glue.format_context();
54
55 if (!glue.OpenContext())
56 return false;
57
58 if (avformat_find_stream_info(format_context, NULL) < 0)
59 return false;
60
61 // Remember the codec for any decodable audio or video streams.
62 std::map<int, StreamContext> stream_contexts;
63 for (size_t i = 0; i < format_context->nb_streams; ++i) {
64 AVCodecContext* c = format_context->streams[i]->codec;
65 if (c->codec_type == AVMEDIA_TYPE_AUDIO ||
66 c->codec_type == AVMEDIA_TYPE_VIDEO) {
67 AVCodec* codec = avcodec_find_decoder(c->codec_id);
68 if (codec && avcodec_open2(c, codec, NULL) >= 0) {
69 stream_contexts[i].codec_context = c;
70 stream_contexts[i].codec = codec;
DaleCurtis 2013/08/08 21:04:33 Doesn't look like you actually use codec anywhere.
vandebo (ex-Chrome) 2013/08/08 23:04:18 Done.
71 }
72 }
73 }
74
75 if (stream_contexts.size() == 0)
76 return false;
77
78 AVPacket packet;
79 scoped_ptr_malloc<AVFrame, media::ScopedPtrAVFree> frame(
80 avcodec_alloc_frame());
81 int result = 0;
82
83 base::Time deadline;
DaleCurtis 2013/08/08 21:04:33 const base::Time deadline = base::Time::Now() + ba
vandebo (ex-Chrome) 2013/08/08 23:04:18 Used std::min (negative check time will have the s
84 const base::TimeDelta max_check_time =
85 base::TimeDelta::FromSeconds(kMaxCheckTimeIneconds);
86 if (check_time > max_check_time)
87 deadline = base::Time::Now() + max_check_time;
88 else
89 deadline = base::Time::Now() + check_time;
90
91 do {
92 result = av_read_frame(glue.format_context(), &packet);
93 if (result < 0)
94 break;
95
DaleCurtis 2013/08/08 21:04:33 I think you need an av_dup_packet(&packet) here ot
vandebo (ex-Chrome) 2013/08/08 23:04:18 Done.
96 if (!ContainsKey(stream_contexts, packet.stream_index))
DaleCurtis 2013/08/08 21:04:33 You end up doing multiple map look ups below. Ins
vandebo (ex-Chrome) 2013/08/08 23:04:18 Done.
97 continue;
98
99 int frame_decoded = 0;
100 AVMediaType type =
101 stream_contexts[packet.stream_index].codec_context->codec_type;
102 if (type == AVMEDIA_TYPE_AUDIO) {
103 // A shallow copy of packet so we can slide packet.data as frames are
104 // decoded; otherwise av_free_packet() will corrupt memory.
105 AVPacket temp_packet = packet;
106 do {
107 avcodec_get_frame_defaults(frame.get());
108 result = avcodec_decode_audio4(
109 stream_contexts[packet.stream_index].codec_context, frame.get(),
110 &frame_decoded, &packet);
DaleCurtis 2013/08/08 21:04:33 temp_packet
vandebo (ex-Chrome) 2013/08/08 23:04:18 Done.
111 if (result < 0)
112 break;
113 temp_packet.size -= result;
114 temp_packet.data += result;
115 } while (temp_packet.size > 0);
DaleCurtis 2013/08/08 21:04:33 Extra space.
vandebo (ex-Chrome) 2013/08/08 23:04:18 Done.
vandebo (ex-Chrome) 2013/08/08 23:04:18 BTW - This is what made me think I didn't need the
116 } else if (type == AVMEDIA_TYPE_VIDEO) {
117 avcodec_get_frame_defaults(frame.get());
118 result = avcodec_decode_video2(
119 stream_contexts[packet.stream_index].codec_context, frame.get(),
120 &frame_decoded, &packet);
121 }
122 } while (base::Time::Now() < deadline && read_ok && result >= 0);
123
124 av_free_packet(&packet);
DaleCurtis 2013/08/08 21:04:33 This needs to be inside the while loop.
vandebo (ex-Chrome) 2013/08/08 23:04:18 Done.
125
126 if (result == AVERROR_EOF)
DaleCurtis 2013/08/08 21:04:33 Could be rewritten as: return read_ok && (result =
vandebo (ex-Chrome) 2013/08/08 23:04:18 Done.
127 result = 0;
128 return read_ok && result >= 0;
129 }
130
131 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698