Skip to content

Commit

Permalink
Revert SHA:4ade78211e2920e33a9995e54c8a7e71b55aaf3e.
Browse files Browse the repository at this point in the history
Turned out the corruption is there regardless of that code, so it has to come from somewhere else
  • Loading branch information
jyavenard committed Apr 30, 2011
1 parent ad091ec commit 10d681c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 140 deletions.
169 changes: 32 additions & 137 deletions mythtv/libs/libmyth/audio/audiooutputdigitalencoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,7 @@
// libav headers
extern "C" {
#include "libavutil/mem.h" // for av_free

// copied from libavutil/internal.h
#include "libavutil/common.h" // for AV_GCC_VERSION_AT_LEAST()
#ifndef av_alias
#if HAVE_ATTRIBUTE_MAY_ALIAS && (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(3,3)
# define av_alias __attribute__((may_alias))
#else
# define av_alias
#endif
#endif

#include "libavcodec/avcodec.h"
#if CONFIG_AC3_DECODER
#include "libavcodec/ac3.h"
#ifndef INT_BIT
#define INT_BIT (CHAR_BIT * sizeof(int))
#endif
#include "libavcodec/ac3_parser.h"
#else
#include <a52dec/a52.h>
#endif
}

// MythTV headers
Expand All @@ -40,16 +20,15 @@ extern "C" {
#define LOC QString("DEnc: ")
#define LOC_ERR QString("DEnc, Error: ")

#define MAX_AC3_FRAME_SIZE 6144

AudioOutputDigitalEncoder::AudioOutputDigitalEncoder(void) :
bytes_per_sample(0),
av_context(NULL),
outlen(0),
inlen(0),
one_frame_bytes(0)
one_frame_bytes(0),
m_spdifenc(NULL)
{
in = (char *)(((long)&inbuf + 15) & ~15);
in = (unsigned char *)(((long)&inbuf + 15) & ~15);
}

AudioOutputDigitalEncoder::~AudioOutputDigitalEncoder()
Expand All @@ -65,9 +44,13 @@ void AudioOutputDigitalEncoder::Dispose()
av_free(av_context);
av_context = NULL;
}
if (m_spdifenc)
{
delete m_spdifenc;
m_spdifenc = NULL;
}
}

//CODEC_ID_AC3
bool AudioOutputDigitalEncoder::Init(
CodecID codec_id, int bitrate, int samplerate, int channels)
{
Expand All @@ -83,7 +66,6 @@ bool AudioOutputDigitalEncoder::Init(
// We need to do this when called from mythmusic
avcodec_init();
avcodec_register_all();
// always AC3 as there is no DTS encoder at the moment 2005/1/9
codec = avcodec_find_encoder(CODEC_ID_AC3);
if (!codec)
{
Expand All @@ -107,6 +89,20 @@ bool AudioOutputDigitalEncoder::Init(
return false;
}

if (m_spdifenc)
{
delete m_spdifenc;
}

m_spdifenc = new SPDIFEncoder("spdif", CODEC_ID_AC3);
if (!m_spdifenc->Succeeded())
{
Dispose();
VERBOSE(VB_IMPORTANT, LOC_ERR +
"Could not create spdif muxer");
return false;
}

bytes_per_sample = av_context->channels * sizeof(short);
one_frame_bytes = bytes_per_sample * av_context->frame_size;

Expand All @@ -118,110 +114,10 @@ bool AudioOutputDigitalEncoder::Init(
return true;
}

// from http://www.ebu.ch/CMSimages/en/tec_AES-EBU_eg_tcm6-11890.pdf
// http://en.wikipedia.org/wiki/S/PDIF
typedef struct {
// byte 0
unsigned professional_consumer:1;
unsigned non_data:1;
// 4 - no emphasis
// 6 - 50/15us
// 7 - CCITT J17
unsigned audio_signal_emphasis:3;
unsigned SSFL:1;
// 0
// 1 - 48k
// 2 - 44.1k
// 3 - 32k
unsigned sample_frequency:2;
// byte 1
// 0
// 1 - 2 ch
// 2 - mono
// 3 - prim/sec
// 4 - stereo
unsigned channel_mode:4;
// 0
// 1 - 192 bit block
// 2 - AES18
// 3 - user def
unsigned user_bit_management:4;
// byte 2
// 1 - audio data
// 2 - co-ordn
unsigned auxiliary_bits:3;
// 4 - 16 bits
// 5-7 - redither to 16 bits
unsigned source_word_length:3;
unsigned reserved:2;
// byte 3
unsigned multi_channel_function_description:8;
// byte 4
unsigned digital_audio_reference_signal:2;
unsigned reserved2:6;

} AESHeader;

static int encode_frame(
bool dts,
unsigned char *data,
size_t enc_len)
{
unsigned char *payload = data + 8; // skip header, currently 52 or 54bits
int sample_rate, bit_rate;

// we don't do any length/crc validation of the AC3 frame here; presumably
// the receiver will have enough sense to do that. if someone has a
// receiver that doesn't, here would be a good place to put in a call
// to a52_crc16_block(samples+2, data_size-2) - but what do we do if the
// packet is bad? we'd need to send something that the receiver would
// ignore, and if so, may as well just assume that it will ignore
// anything with a bad CRC...

uint block_len = 0;

if (CONFIG_AC3_DECODER)
{
int err;
AC3HeaderInfo hdr;
GetBitContext gbc;

init_get_bits(&gbc, payload, 54);
err = ff_ac3_parse_header(&gbc, &hdr);

if(err < 0)
enc_len = 0;
else
{
sample_rate = hdr.sample_rate;
bit_rate = hdr.bit_rate;
enc_len = hdr.frame_size;
block_len = AC3_FRAME_SIZE * 4;
}
}

enc_len = std::min((uint)enc_len, block_len - 8);

swab((char *)payload, (char *)payload, enc_len);

// the following values come from libmpcodecs/ad_hwac3.c in mplayer.
// they form a valid IEC958 AC3 header.
data[0] = 0x72;
data[1] = 0xF8;
data[2] = 0x1F;
data[3] = 0x4E;
data[4] = 0x01;
data[5] = 0x00;
data[6] = (enc_len << 3) & 0xFF;
data[7] = (enc_len >> 5) & 0xFF;
memset(payload + enc_len, 0, block_len - 8 - enc_len);

return enc_len;
}

size_t AudioOutputDigitalEncoder::Encode(void *buf, int len, bool isFloat)
{
size_t outsize = 0;
int data_size;

if (isFloat)
inlen += AudioOutputUtil::fromFloat(FORMAT_S16, in + inlen, buf, len);
Expand All @@ -236,24 +132,23 @@ size_t AudioOutputDigitalEncoder::Encode(void *buf, int len, bool isFloat)

while (i < frames)
{
// put data in the correct spot for encode frame
outsize = avcodec_encode_audio(av_context,
((uchar*)out) + outlen + 8,
OUTBUFSIZE - outlen - 8,
m_encodebuffer,
FF_MIN_BUFFER_SIZE,
(short *)(in + i * one_frame_bytes));
if (outsize < 0)
{
VERBOSE(VB_AUDIO, LOC_ERR + "AC-3 encode error");
return outlen;
}

encode_frame(
/*av_context->codec_id==CODEC_ID_DTS*/ false,
(uchar*)out + outlen, outsize
);


outlen += MAX_AC3_FRAME_SIZE;
if (!m_spdifenc)
{
m_spdifenc = new SPDIFEncoder("spdif", CODEC_ID_AC3);
}
m_spdifenc->WriteFrame(m_encodebuffer, outsize);
m_spdifenc->GetData(out + outlen, data_size);
outlen += data_size;
inlen -= one_frame_bytes;
i++;
}
Expand Down
10 changes: 7 additions & 3 deletions mythtv/libs/libmyth/audio/audiooutputdigitalencoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ extern "C" {
#include "libavcodec/avcodec.h"
};

#include "spdifencoder.h"

#define INBUFSIZE 131072
#define OUTBUFSIZE 98304
#define ENCODER_INBUFSIZE INBUFSIZE
Expand All @@ -27,12 +29,14 @@ class AudioOutputDigitalEncoder

private:
AVCodecContext *av_context;
char out[OUTBUFSIZE];
char inbuf[INBUFSIZE+16];
char *in;
unsigned char out[OUTBUFSIZE];
unsigned char inbuf[INBUFSIZE+16];
unsigned char *in;
int outlen;
int inlen;
size_t one_frame_bytes;
uint8_t m_encodebuffer[FF_MIN_BUFFER_SIZE];
SPDIFEncoder *m_spdifenc;
};

#endif

0 comments on commit 10d681c

Please sign in to comment.