#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);
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;
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);
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;
case SCT_AAC:
tracktype = 2;
codec_id = "A_AAC";
+ bit_depth = 16;
break;
case SCT_VORBIS:
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);
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);
}
data += 7;
}
-
ebml_append_id(mkm->cluster, 0xa3 ); // SimpleBlock
ebml_append_size(mkm->cluster, len + 4);
ebml_append_size(mkm->cluster, t->tracknum);
#include "packet.h"
#include "transcoding.h"
#include "libav.h"
+#include "parsers/bitstream.h"
static long transcoder_nrprocessors;
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",
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
+}
/**
*
} 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);
sm = streaming_msg_create_pkt(n);
streaming_target_deliver2(ts->ts_target, sm);
pkt_ref_dec(n);
-
}
av_free_packet(&packet);