Signed-off-by: Ivan <grigoriev.iva...@gmail.com> --- libavformat/flvenc.c | 130 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 78 insertions(+), 52 deletions(-)
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c index d62ff70..3536e9a 100644 --- a/libavformat/flvenc.c +++ b/libavformat/flvenc.c @@ -343,12 +343,74 @@ static int unsupported_codec(AVFormatContext *s, return AVERROR(ENOSYS); } +static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par) { + int64_t data_size; + AVIOContext *pb = s->pb; + FLVContext *flv = s->priv_data; + + if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264 + || par->codec_id == AV_CODEC_ID_MPEG4) { + int64_t pos; + avio_w8(pb, + par->codec_type == AVMEDIA_TYPE_VIDEO ? + FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO); + avio_wb24(pb, 0); // size patched later + avio_wb24(pb, 0); // ts + avio_w8(pb, 0); // ts ext + avio_wb24(pb, 0); // streamid + pos = avio_tell(pb); + if (par->codec_id == AV_CODEC_ID_AAC) { + avio_w8(pb, get_audio_flags(s, par)); + avio_w8(pb, 0); // AAC sequence header + + if (!par->extradata_size && flv->flags & 1) { + PutBitContext pbc; + int samplerate_index; + int channels = flv->audio_par->channels + - (flv->audio_par->channels == 8 ? 1 : 0); + uint8_t data[2]; + + for (samplerate_index = 0; samplerate_index < 16; + samplerate_index++) + if (flv->audio_par->sample_rate + == mpeg4audio_sample_rates[samplerate_index]) + break; + + init_put_bits(&pbc, data, sizeof(data)); + put_bits(&pbc, 5, flv->audio_par->profile + 1); //profile + put_bits(&pbc, 4, samplerate_index); //sample rate index + put_bits(&pbc, 4, channels); + put_bits(&pbc, 1, 0); //frame length - 1024 samples + put_bits(&pbc, 1, 0); //does not depend on core coder + put_bits(&pbc, 1, 0); //is not extension + flush_put_bits(&pbc); + + avio_w8(pb, data[0]); + avio_w8(pb, data[1]); + + av_log(s, AV_LOG_WARNING, "AAC sequence header: %02x %02x.\n", + data[0], data[1]); + } + avio_write(pb, par->extradata, par->extradata_size); + } else { + avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags + avio_w8(pb, 0); // AVC sequence header + avio_wb24(pb, 0); // composition time + ff_isom_write_avcc(pb, par->extradata, par->extradata_size); + } + data_size = avio_tell(pb) - pos; + avio_seek(pb, -data_size - 10, SEEK_CUR); + avio_wb24(pb, data_size); + avio_skip(pb, data_size + 10 - 3); + avio_wb32(pb, data_size + 11); // previous tag size + } +} + static int flv_write_header(AVFormatContext *s) { int i; AVIOContext *pb = s->pb; FLVContext *flv = s->priv_data; - int64_t data_size; for (i = 0; i < s->nb_streams; i++) { AVCodecParameters *par = s->streams[i]->codecpar; @@ -446,57 +508,7 @@ static int flv_write_header(AVFormatContext *s) write_metadata(s, 0); for (i = 0; i < s->nb_streams; i++) { - AVCodecParameters *par = s->streams[i]->codecpar; - if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) { - int64_t pos; - avio_w8(pb, par->codec_type == AVMEDIA_TYPE_VIDEO ? - FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO); - avio_wb24(pb, 0); // size patched later - avio_wb24(pb, 0); // ts - avio_w8(pb, 0); // ts ext - avio_wb24(pb, 0); // streamid - pos = avio_tell(pb); - if (par->codec_id == AV_CODEC_ID_AAC) { - avio_w8(pb, get_audio_flags(s, par)); - avio_w8(pb, 0); // AAC sequence header - - if (!par->extradata_size && flv->flags & 1) { - PutBitContext pbc; - int samplerate_index; - int channels = flv->audio_par->channels - (flv->audio_par->channels == 8 ? 1 : 0); - uint8_t data[2]; - - for (samplerate_index = 0; samplerate_index < 16; samplerate_index++) - if (flv->audio_par->sample_rate == mpeg4audio_sample_rates[samplerate_index]) - break; - - init_put_bits(&pbc, data, sizeof(data)); - put_bits(&pbc, 5, flv->audio_par->profile + 1); //profile - put_bits(&pbc, 4, samplerate_index); //sample rate index - put_bits(&pbc, 4, channels); - put_bits(&pbc, 1, 0); //frame length - 1024 samples - put_bits(&pbc, 1, 0); //does not depend on core coder - put_bits(&pbc, 1, 0); //is not extension - flush_put_bits(&pbc); - - avio_w8(pb, data[0]); - avio_w8(pb, data[1]); - - av_log(s, AV_LOG_WARNING, "AAC sequence header: %02x %02x.\n", data[0], data[1]); - } - avio_write(pb, par->extradata, par->extradata_size); - } else { - avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags - avio_w8(pb, 0); // AVC sequence header - avio_wb24(pb, 0); // composition time - ff_isom_write_avcc(pb, par->extradata, par->extradata_size); - } - data_size = avio_tell(pb) - pos; - avio_seek(pb, -data_size - 10, SEEK_CUR); - avio_wb24(pb, data_size); - avio_skip(pb, data_size + 10 - 3); - avio_wb32(pb, data_size + 11); // previous tag size - } + flv_write_codec_header(s, s->streams[i]->codecpar); } return 0; @@ -554,6 +566,20 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) else flags_size = 1; + if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264 + || par->codec_id == AV_CODEC_ID_MPEG4) { + int side_size = 0; + uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size); + if (side && side_size > 0 && (side_size != par->extradata_size || !memcmp(side, par->extradata, side_size))) { + av_free(par->extradata); + par->extradata = av_mallocz(side_size + AV_INPUT_BUFFER_PADDING_SIZE); + memcpy(par->extradata, side, side_size); + par->extradata_size = side_size; + flv_write_codec_header(s, par); + } + } + + if (flv->delay == AV_NOPTS_VALUE) flv->delay = -pkt->dts; -- 1.9.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel