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

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: exclude test when source is excluded 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/time/time.h"
11 #include "media/ffmpeg/ffmpeg_common.h"
12 #include "media/filters/blocking_url_protocol.h"
13 #include "media/filters/ffmpeg_glue.h"
14 #include "media/filters/file_data_source.h"
15
16 namespace media {
17
18 namespace {
DaleCurtis 2013/08/09 00:58:04 media codebase prefers static to unnamed namespace
vandebo (ex-Chrome) 2013/08/09 04:26:14 But static is deprecated in namespace scope... Don
19
20 const int64 kMaxCheckTimeInSeconds = 5;
21
22 void OnError(bool* called) {
23 *called = false;
24 }
25
26 } // namespace
27
28 MediaFileChecker::MediaFileChecker(const base::PlatformFile& file)
29 : file_(file),
30 file_closer_(&file_) {
31 }
32
33 MediaFileChecker::~MediaFileChecker() {
34 }
35
36 bool MediaFileChecker::Start(base::TimeDelta check_time) {
37 media::FileDataSource source;
38 bool read_ok = true;
39 media::BlockingUrlProtocol protocol(&source, base::Bind(&OnError, &read_ok));
40 media::FFmpegGlue glue(&protocol);
41 source.InitializeFromPlatformFile(file_);
42 AVFormatContext* format_context = glue.format_context();
43
44 if (!glue.OpenContext())
45 return false;
46
47 if (avformat_find_stream_info(format_context, NULL) < 0)
48 return false;
49
50 // Remember the codec context for any decodable audio or video streams.
51 std::map<int, AVCodecContext*> stream_contexts;
52 for (size_t i = 0; i < format_context->nb_streams; ++i) {
53 AVCodecContext* c = format_context->streams[i]->codec;
54 if (c->codec_type == AVMEDIA_TYPE_AUDIO ||
55 c->codec_type == AVMEDIA_TYPE_VIDEO) {
56 AVCodec* codec = avcodec_find_decoder(c->codec_id);
57 if (codec && avcodec_open2(c, codec, NULL) >= 0) {
DaleCurtis 2013/08/09 00:58:04 No {} to keep style w/ rest of file.
vandebo (ex-Chrome) 2013/08/09 04:26:14 Oops, Done.
58 stream_contexts[i] = c;
59 }
60 }
61 }
62
63 if (stream_contexts.size() == 0)
64 return false;
65
66 AVPacket packet;
67 scoped_ptr_malloc<AVFrame, media::ScopedPtrAVFree> frame(
68 avcodec_alloc_frame());
69 int result = 0;
70
71 base::Time deadline = base::Time::Now() +
72 std::min(check_time,
73 base::TimeDelta::FromSeconds(kMaxCheckTimeInSeconds));
74 do {
75 result = av_read_frame(glue.format_context(), &packet);
76 if (result < 0)
77 break;
78 result = av_dup_packet(&packet);
79 if (result < 0)
80 break;
81
82 std::map<int, AVCodecContext*>::const_iterator it =
83 stream_contexts.find(packet.stream_index);
84 if (it == stream_contexts.end()) {
85 av_free_packet(&packet);
86 continue;
87 }
88 AVCodecContext* av_context = it->second;
89
90 int frame_decoded = 0;
91 if (av_context->codec_type == AVMEDIA_TYPE_AUDIO) {
92 // A shallow copy of packet so we can slide packet.data as frames are
93 // decoded; otherwise av_free_packet() will corrupt memory.
94 AVPacket temp_packet = packet;
95 do {
96 avcodec_get_frame_defaults(frame.get());
97 result = avcodec_decode_audio4(av_context, frame.get(), &frame_decoded,
98 &temp_packet);
99 if (result < 0)
100 break;
101 temp_packet.size -= result;
102 temp_packet.data += result;
103 } while (temp_packet.size > 0);
104 } else if (av_context->codec_type == AVMEDIA_TYPE_VIDEO) {
105 avcodec_get_frame_defaults(frame.get());
106 result = avcodec_decode_video2(av_context, frame.get(), &frame_decoded,
107 &packet);
108 }
109 av_free_packet(&packet);
110 } while (base::Time::Now() < deadline && read_ok && result >= 0);
111
112 return read_ok && (result == AVERROR_EOF || result >= 0);
113 }
114
115 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698