Revert "[M120 Migration]Fix for crash during chrome exit"
[platform/framework/web/chromium-efl.git] / media / filters / ffmpeg_h264_to_annex_b_bitstream_converter.cc
1 // Copyright 2012 The Chromium Authors
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/filters/ffmpeg_h264_to_annex_b_bitstream_converter.h"
6
7 #include <stdint.h>
8
9 #include "base/logging.h"
10 #include "media/ffmpeg/ffmpeg_common.h"
11 #include "media/formats/mp4/box_definitions.h"
12
13 namespace media {
14
15 FFmpegH264ToAnnexBBitstreamConverter::FFmpegH264ToAnnexBBitstreamConverter(
16     AVCodecParameters* stream_codec_parameters)
17     : configuration_processed_(false),
18       stream_codec_parameters_(stream_codec_parameters) {
19   CHECK(stream_codec_parameters_);
20 }
21
22 FFmpegH264ToAnnexBBitstreamConverter::~FFmpegH264ToAnnexBBitstreamConverter() =
23     default;
24
25 bool FFmpegH264ToAnnexBBitstreamConverter::ConvertPacket(AVPacket* packet) {
26   std::unique_ptr<mp4::AVCDecoderConfigurationRecord> avc_config;
27
28   if (packet == NULL || !packet->data) {
29     DVLOG(2) << __func__ << ": Null or empty packet";
30     return false;
31   }
32
33   // Calculate the needed output buffer size.
34   if (!configuration_processed_) {
35     if (!stream_codec_parameters_->extradata ||
36         stream_codec_parameters_->extradata_size <= 0) {
37       DVLOG(2) << __func__ << ": Empty extra data";
38       return false;
39     }
40
41     avc_config = std::make_unique<mp4::AVCDecoderConfigurationRecord>();
42
43     if (!converter_.ParseConfiguration(stream_codec_parameters_->extradata,
44                                        stream_codec_parameters_->extradata_size,
45                                        avc_config.get())) {
46       DVLOG(2) << __func__ << ": ParseConfiguration() failure";
47       return false;
48     }
49   }
50
51   uint32_t output_packet_size = converter_.CalculateNeededOutputBufferSize(
52       packet->data, packet->size, avc_config.get());
53
54   if (output_packet_size == 0) {
55     DVLOG(2) << __func__ << ": zero |output_packet_size|";
56     return false;  // Invalid input packet.
57   }
58
59   // Allocate new packet for the output.
60   AVPacket dest_packet;
61   if (av_new_packet(&dest_packet, output_packet_size) != 0) {
62     DVLOG(2) << __func__ << ": Memory allocation failure";
63     return false;
64   }
65
66   // This is a bit tricky: since the interface does not allow us to replace
67   // the pointer of the old packet with a new one, we will initially copy the
68   // metadata from old packet to new bigger packet.
69   av_packet_copy_props(&dest_packet, packet);
70
71   // Proceed with the conversion of the actual in-band NAL units, leave room
72   // for configuration in the beginning.
73   uint32_t io_size = dest_packet.size;
74   if (!converter_.ConvertNalUnitStreamToByteStream(
75           packet->data, packet->size,
76           avc_config.get(),
77           dest_packet.data, &io_size)) {
78     DVLOG(2) << __func__ << ": ConvertNalUnitStreamToByteStream() failure";
79     return false;
80   }
81
82   if (avc_config)
83     configuration_processed_ = true;
84
85   // At the end we must destroy the old packet.
86   av_packet_unref(packet);
87
88   // Finally, replace the values in the input packet.
89   memcpy(packet, &dest_packet, sizeof(*packet));
90   return true;
91 }
92
93 }  // namespace media