00001 #include "config.h"
00002
00003 #include "mythcorecontext.h"
00004
00005 #include "compat.h"
00006 #include "spdifencoder.h"
00007 #include "mythlogging.h"
00008 extern "C" {
00009 #include "libavformat/avformat.h"
00010 #include "libavutil/opt.h"
00011 }
00012
00013 #define LOC QString("SPDIFEncoder: ")
00014
00024 SPDIFEncoder::SPDIFEncoder(QString muxer, int codec_id)
00025 : m_complete(false), m_oc(NULL), m_stream(NULL), m_size(0)
00026 {
00027 QByteArray dev_ba = muxer.toAscii();
00028 AVOutputFormat *fmt;
00029
00030 avcodeclock->lock();
00031 av_register_all();
00032 avcodeclock->unlock();
00033
00034 fmt = av_guess_format(dev_ba.constData(), NULL, NULL);
00035 if (!fmt)
00036 {
00037 LOG(VB_AUDIO, LOG_ERR, LOC + "av_guess_format");
00038 return;
00039 }
00040
00041 m_oc = avformat_alloc_context();
00042 if (!m_oc)
00043 {
00044 LOG(VB_AUDIO, LOG_ERR, LOC + "avformat_alloc_context");
00045 return;
00046 }
00047 m_oc->oformat = fmt;
00048
00049 m_oc->pb = avio_alloc_context(m_buffer, sizeof(m_buffer), 0,
00050 this, NULL, funcIO, NULL);
00051 if (!m_oc->pb)
00052 {
00053 LOG(VB_AUDIO, LOG_ERR, LOC + "avio_alloc_context");
00054 Destroy();
00055 return;
00056 }
00057
00058 m_oc->pb->seekable = 0;
00059 m_oc->flags |= AVFMT_NOFILE | AVFMT_FLAG_IGNIDX;
00060
00061 m_stream = avformat_new_stream(m_oc, NULL);
00062 if (!m_stream)
00063 {
00064 LOG(VB_AUDIO, LOG_ERR, LOC + "avformat_new_stream");
00065 Destroy();
00066 return;
00067 }
00068
00069 m_stream->id = 1;
00070
00071 AVCodecContext *codec = m_stream->codec;
00072
00073 codec->codec_id = (CodecID)codec_id;
00074 avformat_write_header(m_oc, NULL);
00075
00076 LOG(VB_AUDIO, LOG_INFO, LOC + QString("Creating %1 encoder (for %2)")
00077 .arg(muxer).arg(ff_codec_id_string((CodecID)codec_id)));
00078
00079 m_complete = true;
00080 }
00081
00082 SPDIFEncoder::~SPDIFEncoder(void)
00083 {
00084 Destroy();
00085 }
00086
00092 void SPDIFEncoder::WriteFrame(unsigned char *data, int size)
00093 {
00094 AVPacket packet;
00095 av_init_packet(&packet);
00096 static int pts = 1;
00097 packet.pts = pts++;
00098 packet.data = data;
00099 packet.size = size;
00100
00101 if (av_write_frame(m_oc, &packet) < 0)
00102 {
00103 LOG(VB_AUDIO, LOG_ERR, LOC + "av_write_frame");
00104 }
00105 }
00106
00113 int SPDIFEncoder::GetData(unsigned char *buffer, int &dest_size)
00114 {
00115 if(m_size > 0)
00116 {
00117 memcpy(buffer, m_buffer, m_size);
00118 dest_size = m_size;
00119 m_size = 0;
00120 return dest_size;
00121 }
00122 return -1;
00123 }
00124
00128 void SPDIFEncoder::Reset()
00129 {
00130 m_size = 0;
00131 }
00132
00139 bool SPDIFEncoder::SetMaxHDRate(int rate)
00140 {
00141 if (!m_oc)
00142 {
00143 return false;
00144 }
00145 av_opt_set_int(m_oc->priv_data, "dtshd_rate", rate, 0);
00146 return true;
00147 }
00148
00152 int SPDIFEncoder::funcIO(void *opaque, unsigned char *buf, int size)
00153 {
00154 SPDIFEncoder *enc = (SPDIFEncoder *)opaque;
00155
00156 memcpy(enc->m_buffer + enc->m_size, buf, size);
00157 enc->m_size += size;
00158 return size;
00159 }
00160
00164 void SPDIFEncoder::Destroy()
00165 {
00166 Reset();
00167
00168 if (m_complete)
00169 {
00170 av_write_trailer(m_oc);
00171 }
00172
00173 if (m_stream)
00174 {
00175 delete[] m_stream->codec->extradata;
00176 avcodec_close(m_stream->codec);
00177 av_freep(&m_stream);
00178 }
00179
00180 if (m_oc )
00181 {
00182 if (m_oc->pb)
00183 {
00184 av_freep(&m_oc->pb);
00185 }
00186 av_freep(&m_oc);
00187 }
00188 }