15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/ffmpeg_h264_to_annex_b_bitstream_converter.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/ffmpeg/ffmpeg_common.h"
9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "media/formats/mp4/box_definitions.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FFmpegH264ToAnnexBBitstreamConverter::FFmpegH264ToAnnexBBitstreamConverter(
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AVCodecContext* stream_context)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : configuration_processed_(false),
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      stream_context_(stream_context) {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(stream_context_);
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FFmpegH264ToAnnexBBitstreamConverter::~FFmpegH264ToAnnexBBitstreamConverter() {}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FFmpegH264ToAnnexBBitstreamConverter::ConvertPacket(AVPacket* packet) {
23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_ptr<mp4::AVCDecoderConfigurationRecord> avc_config;
24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (packet == NULL || !packet->data)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calculate the needed output buffer size.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!configuration_processed_) {
30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (!stream_context_->extradata || stream_context_->extradata_size <= 0)
31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return false;
32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    avc_config.reset(new mp4::AVCDecoderConfigurationRecord());
34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (!converter_.ParseConfiguration(
36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            stream_context_->extradata,
37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            stream_context_->extradata_size,
38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            avc_config.get())) {
39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return false;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  uint32 output_packet_size = converter_.CalculateNeededOutputBufferSize(
44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      packet->data, packet->size, avc_config.get());
45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (output_packet_size == 0)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;  // Invalid input packet.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allocate new packet for the output.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AVPacket dest_packet;
51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (av_new_packet(&dest_packet, output_packet_size) != 0)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;  // Memory allocation failure.
53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is a bit tricky: since the interface does not allow us to replace
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the pointer of the old packet with a new one, we will initially copy the
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // metadata from old packet to new bigger packet.
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  av_packet_copy_props(&dest_packet, packet);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Proceed with the conversion of the actual in-band NAL units, leave room
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for configuration in the beginning.
61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  uint32 io_size = dest_packet.size;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!converter_.ConvertNalUnitStreamToByteStream(
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          packet->data, packet->size,
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          avc_config.get(),
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          dest_packet.data, &io_size)) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (avc_config)
70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    configuration_processed_ = true;
71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At the end we must destroy the old packet.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  av_free_packet(packet);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *packet = dest_packet;  // Finally, replace the values in the input packet.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
80