AAC fixes (ADTS header) in transcoder and libav muxer

This commit is contained in:
Jaroslav Kysela 2014-10-17 17:25:36 +02:00
parent 8e876995f3
commit e393311e27
5 changed files with 62 additions and 15 deletions

View file

@ -79,6 +79,7 @@ streaming_component_type2codec_id(streaming_component_type_t type)
case SCT_EAC3:
codec_id = AV_CODEC_ID_EAC3;
break;
case SCT_MP4A:
case SCT_AAC:
codec_id = AV_CODEC_ID_AAC;
break;

View file

@ -114,6 +114,8 @@ lav_muxer_add_stream(lav_muxer_t *lm,
#if 0
c->time_base.num = 1;
c->time_base.den = c->sample_rate;
#else
c->time_base = st->time_base;
#endif
av_dict_set(&st->metadata, "language", ssc->ssc_lang, 0);
@ -123,10 +125,8 @@ lav_muxer_add_stream(lav_muxer_t *lm,
c->width = ssc->ssc_width;
c->height = ssc->ssc_height;
#if 0
c->time_base.num = 1;
c->time_base.num = 1;
c->time_base.den = 25;
#endif
c->sample_aspect_ratio.num = ssc->ssc_aspect_num;
c->sample_aspect_ratio.den = ssc->ssc_aspect_den;
@ -396,6 +396,10 @@ lav_muxer_write_pkt(muxer_t *m, streaming_message_type_t smt, void *data)
tvhlog(LOG_WARNING, "libav", "Failed to filter bitstream");
break;
}
} else if (st->codec->codec_id == AV_CODEC_ID_AAC) {
/* remove ADTS header */
packet.data = pktbuf_ptr(pkt->pkt_payload) + 7;
packet.size = pktbuf_len(pkt->pkt_payload) - 7;
} else {
packet.data = pktbuf_ptr(pkt->pkt_payload);
packet.size = pktbuf_len(pkt->pkt_payload);

View file

@ -236,6 +236,7 @@ mk_build_tracks(mk_mux_t *mkm, const streaming_start_t *ss)
htsbuf_queue_t *q = htsbuf_queue_alloc(0), *t;
int tracknum = 0;
uint8_t buf4[4];
uint32_t bit_depth = 0;
mkm->tracks = calloc(1, sizeof(mk_track_t) * ss->ss_num_components);
mkm->ntracks = ss->ss_num_components;
@ -302,6 +303,7 @@ mk_build_tracks(mk_mux_t *mkm, const streaming_start_t *ss)
case SCT_AAC:
tracktype = 2;
codec_id = "A_AAC";
bit_depth = 16;
break;
case SCT_VORBIS:
@ -385,15 +387,13 @@ mk_build_tracks(mk_mux_t *mkm, const streaming_start_t *ss)
break;
}
if(ssc->ssc_frameduration) {
int d = ts_rescale(ssc->ssc_frameduration, 1000000000);
ebml_append_uint(t, 0x23e383, d);
}
if(SCT_ISVIDEO(ssc->ssc_type)) {
htsbuf_queue_t *vi = htsbuf_queue_alloc(0);
if(ssc->ssc_frameduration) {
int d = ts_rescale(ssc->ssc_frameduration, 1000000000);
ebml_append_uint(t, 0x23e383, d);
}
ebml_append_uint(vi, 0xb0, ssc->ssc_width);
ebml_append_uint(vi, 0xba, ssc->ssc_height);
@ -416,6 +416,8 @@ mk_build_tracks(mk_mux_t *mkm, const streaming_start_t *ss)
ebml_append_float(au, 0xb5, sri_to_rate(ssc->ssc_sri));
ebml_append_uint(au, 0x9f, ssc->ssc_channels);
if (bit_depth)
ebml_append_uint(au, 0x6264, bit_depth);
ebml_append_master(t, 0xe1, au);
}
@ -979,7 +981,6 @@ mk_write_frame_i(mk_mux_t *mkm, mk_track_t *t, th_pkt_t *pkt)
data += 7;
}
ebml_append_id(mkm->cluster, 0xa3 ); // SimpleBlock
ebml_append_size(mkm->cluster, len + 4);
ebml_append_size(mkm->cluster, t->tracknum);

View file

@ -37,6 +37,7 @@
#include "packet.h"
#include "transcoding.h"
#include "libav.h"
#include "parsers/bitstream.h"
static long transcoder_nrprocessors;
@ -200,6 +201,10 @@ transcoder_get_decoder(transcoder_t *t, streaming_component_type_t ty)
enum AVCodecID codec_id;
AVCodec *codec;
/* the MP4A and AAC packet format is same, reduce to one type */
if (ty == SCT_MP4A)
ty = SCT_AAC;
codec_id = streaming_component_type2codec_id(ty);
if (codec_id == AV_CODEC_ID_NONE) {
tvherror("transcode", "%04X: Unsupported input codec %s",
@ -313,6 +318,31 @@ transcoder_stream_subtitle(transcoder_t *t, transcoder_stream_t *ts, th_pkt_t *p
avsubtitle_free(&sub);
}
static void
create_adts_header(pktbuf_t *pb, int sri, int channels)
{
bitstream_t bs;
/* 7 bytes of ADTS header */
init_wbits(&bs, pktbuf_ptr(pb), 56);
put_bits(&bs, 0xfff, 12); // Sync marker
put_bits(&bs, 0, 1); // ID 0 = MPEG 4
put_bits(&bs, 0, 2); // Layer
put_bits(&bs, 1, 1); // Protection absent
put_bits(&bs, 2, 2); // AOT
put_bits(&bs, sri, 4);
put_bits(&bs, 1, 1); // Private bit
put_bits(&bs, channels, 3);
put_bits(&bs, 1, 1); // Original
put_bits(&bs, 1, 1); // Copy
put_bits(&bs, 1, 1); // Copyright identification bit
put_bits(&bs, 1, 1); // Copyright identification start
put_bits(&bs, pktbuf_len(pb), 13);
put_bits(&bs, 0, 11); // Buffer fullness
put_bits(&bs, 0, 2); // RDB in frame
}
/**
*
@ -690,12 +720,24 @@ transcoder_stream_audio(transcoder_t *t, transcoder_stream_t *ts, th_pkt_t *pkt)
} else if (got_packet_ptr && packet.pts >= 0) {
n = pkt_alloc(packet.data, packet.size, packet.pts, packet.pts);
int extra_size = 0;
if (ts->ts_type == SCT_AAC) {
/* only if ADTS header is missing, create it */
if (packet.size < 2 || packet.data[0] != 0xff || (packet.data[1] & 0xf0) != 0xf0)
extra_size = 7;
}
n = pkt_alloc(NULL, packet.size + extra_size, packet.pts, packet.pts);
memcpy(pktbuf_ptr(n->pkt_payload) + extra_size, packet.data, packet.size);
n->pkt_componentindex = ts->ts_index;
n->pkt_channels = octx->channels;
n->pkt_sri = rate_to_sri(octx->sample_rate);
n->pkt_duration = packet.duration;
n->pkt_duration = packet.duration;
if (extra_size && ts->ts_type == SCT_AAC)
create_adts_header(pkt->pkt_payload, n->pkt_sri, octx->channels);
if (octx->extradata_size)
n->pkt_header = pktbuf_alloc(octx->extradata, octx->extradata_size);
@ -705,7 +747,6 @@ transcoder_stream_audio(transcoder_t *t, transcoder_stream_t *ts, th_pkt_t *pkt)
sm = streaming_msg_create_pkt(n);
streaming_target_deliver2(ts->ts_target, sm);
pkt_ref_dec(n);
}
av_free_packet(&packet);

View file

@ -222,11 +222,11 @@ typedef enum {
SCT_TELETEXT,
SCT_DVBSUB,
SCT_CA,
SCT_AAC,
SCT_AAC, /* AAC-LATM in MPEG-TS, ADTS + AAC in packet form */
SCT_MPEGTS,
SCT_TEXTSUB,
SCT_EAC3,
SCT_MP4A,
SCT_MP4A, /* ADTS + AAC in MPEG-TS and packet form */
SCT_VP8,
SCT_VORBIS,
SCT_HEVC,