[prev in list] [next in list] [prev in thread] [next in thread]
List: mplayer-dev-eng
Subject: [MPlayer-dev-eng] [RFC][PATCH] libmpcodecs/ad_spdif.c check DTS profile
From: Naoya OYAMA <naoya.oyama () gmail ! com>
Date: 2012-02-08 14:39:23
Message-ID: CAJz3U+USUhuXvUDRgZY_z7XErDKxpoanKe1dEfT8huTiK0R16A () mail ! gmail ! com
[Download RAW message or body]
Hi,
Attached patch for ad_spdif.
Improvement enumerated below was added.
1. A suitable value is set up for bitrate and channels and dtshd_rate.
By useing DTS profile.
2. The code for creating lavc is diverted from ad_ffmpeg.c.
3. By creating lavc on ad_spdif.c, detection of bitrate and
sample_rate became highly precise.
Thanks.
["mplayer_spdif_lavc.diff" (text/x-patch)]
Index: libmpcodecs/ad_spdif.c
===================================================================
--- libmpcodecs/ad_spdif.c (revision 34655)
+++ libmpcodecs/ad_spdif.c (working copy)
@@ -25,6 +25,9 @@
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libavutil/opt.h"
+#include "dec_audio.h"
+#include "help_mp.h"
+#include "libavutil/dict.h"
static const ad_info_t info = {
"libavformat/spdifenc audio pass-through decoder.",
@@ -39,11 +42,16 @@
#define FILENAME_SPDIFENC "spdif"
#define OUTBUF_SIZE 65536
struct spdifContext {
+ AVCodecContext *lavc_ctx;
AVFormatContext *lavf_ctx;
int iec61937_packet_size;
+ int init_buffer_len;
+ int init_buffer_pos;
+ int initialized;
int out_buffer_len;
int out_buffer_size;
uint8_t *out_buffer;
+ uint8_t init_buffer[OUTBUF_SIZE];
uint8_t pb_buffer[OUTBUF_SIZE];
};
@@ -78,24 +86,26 @@
static int init(sh_audio_t *sh)
{
- int i, x, in_size, srate, bps, *dtshd_rate;
- unsigned char *start;
- double pts;
+ int i, x, srate, bps, *dtshd_rate;
+ char tmpstr[50];
static const struct {
const char *name; enum CodecID id;
} fmt_id_type[] = {
- { "aac" , CODEC_ID_AAC },
- { "ac3" , CODEC_ID_AC3 },
- { "dca" , CODEC_ID_DTS },
- { "eac3", CODEC_ID_EAC3 },
- { "mpa" , CODEC_ID_MP3 },
- { "thd" , CODEC_ID_TRUEHD },
- { NULL , 0 }
+ { "aac" , CODEC_ID_AAC },
+ { "ac3" , CODEC_ID_AC3 },
+ { "dca" , CODEC_ID_DTS },
+ { "eac3" , CODEC_ID_EAC3 },
+ { "mpa" , CODEC_ID_MP3 },
+ { "truehd", CODEC_ID_TRUEHD },
+ { NULL , 0 }
};
- AVFormatContext *lavf_ctx = NULL;
- AVStream *stream = NULL;
- const AVOption *opt = NULL;
- struct spdifContext *spdif_ctx = NULL;
+ AVFormatContext *lavf_ctx = NULL;
+ AVStream *stream = NULL;
+ AVCodecContext *lavc_ctx = NULL;
+ AVCodec *lavc_codec = NULL;
+ AVDictionary *opts = NULL;
+ const AVOption *opt = NULL;
+ struct spdifContext *spdif_ctx = NULL;
spdif_ctx = av_mallocz(sizeof(*spdif_ctx));
if (!spdif_ctx)
@@ -103,6 +113,9 @@
spdif_ctx->lavf_ctx = avformat_alloc_context();
if (!spdif_ctx->lavf_ctx)
goto fail;
+ spdif_ctx->initialized = 0;
+ spdif_ctx->init_buffer_len = 0;
+ spdif_ctx->init_buffer_pos = 0;
sh->context = spdif_ctx;
lavf_ctx = spdif_ctx->lavf_ctx;
@@ -135,86 +148,166 @@
"This codec is not supported by spdifenc.\n");
goto fail;
}
+ lavc_codec = avcodec_find_decoder_by_name(sh->codec->dll);
+ if(!lavc_codec){
+ mp_msg(MSGT_DECAUDIO,MSGL_ERR,MSGTR_MissingLAVCcodec,sh->codec->dll);
+ goto fail;
+ }
- // get sample_rate & bitrate from parser
- bps = srate = 0;
- x = ds_get_packet_pts(sh->ds, &start, &pts);
- in_size = x;
- if (x <= 0) {
- pts = MP_NOPTS_VALUE;
- x = 0;
+ // create avcodec
+ lavc_ctx = avcodec_alloc_context3(lavc_codec);
+ spdif_ctx->lavc_ctx = lavc_ctx;
+ snprintf(tmpstr, sizeof(tmpstr), "%f", drc_level);
+ av_dict_set(&opts, "drc_scale", tmpstr, 0);
+ lavc_ctx->sample_rate = sh->samplerate;
+ lavc_ctx->bit_rate = sh->i_bps * 8;
+ if(sh->wf){
+ lavc_ctx->channels = sh->wf->nChannels;
+ lavc_ctx->sample_rate = sh->wf->nSamplesPerSec;
+ lavc_ctx->bit_rate = sh->wf->nAvgBytesPerSec * 8;
+ lavc_ctx->block_align = sh->wf->nBlockAlign;
+ lavc_ctx->bits_per_coded_sample = sh->wf->wBitsPerSample;
}
- ds_parse(sh->ds, &start, &x, pts, 0);
- if (x == 0) { // not enough buffer
- srate = 48000; //fake value
- bps = 768000/8; //fake value
- } else if (sh->avctx) {
- if (sh->avctx->sample_rate < 44100) {
- mp_msg(MSGT_DECAUDIO,MSGL_INFO,
- "This stream sample_rate[%d Hz] may be broken. "
- "Force reset 48000Hz.\n",
- sh->avctx->sample_rate);
- srate = 48000; //fake value
- } else
- srate = sh->avctx->sample_rate;
- bps = sh->avctx->bit_rate/8;
+ lavc_ctx->request_channels = audio_output_channels;
+ lavc_ctx->codec_tag = sh->format; //FOURCC
+ lavc_ctx->codec_id = lavc_codec->id; // not sure if required, imho not --A'rpi
+
+ // alloc extra data
+ if (sh->wf && sh->wf->cbSize > 0) {
+ lavc_ctx->extradata = av_mallocz(sh->wf->cbSize
+ + FF_INPUT_BUFFER_PADDING_SIZE);
+ lavc_ctx->extradata_size = sh->wf->cbSize;
+ memcpy(lavc_ctx->extradata, sh->wf + 1,
+ lavc_ctx->extradata_size);
}
- sh->ds->buffer_pos -= in_size;
+ // for QDM2
+ if (sh->codecdata_len && sh->codecdata
+ && !lavc_ctx->extradata)
+ {
+ lavc_ctx->extradata = av_malloc(sh->codecdata_len);
+ lavc_ctx->extradata_size = sh->codecdata_len;
+ memcpy(lavc_ctx->extradata, (char *)sh->codecdata,
+ lavc_ctx->extradata_size);
+ }
+
+ // open it
+ if (avcodec_open2(lavc_ctx, lavc_codec, &opts) < 0) {
+ mp_msg(MSGT_DECAUDIO,MSGL_ERR, MSGTR_CantOpenCodec);
+ return 0;
+ }
+ av_dict_free(&opts);
+ mp_msg(MSGT_DECAUDIO,MSGL_V,"INFO: libavcodec \"%s\" init OK!\n",
+ lavc_codec->name);
+
+ // Decode at least 1 byte: (to get header filled)
+ for (x = i = 0; i < 5 && x <= 0; i++) {
+ x = decode_audio(sh, spdif_ctx->init_buffer, 1,
+ sizeof(spdif_ctx->init_buffer));
+ spdif_ctx->init_buffer_len += x;
+ }
+#if 0
+ if (!sh->avctx) {
+ mp_msg(MSGT_DECAUDIO,MSGL_V,
+ "lavc_ctx: bit_rate[%d] sample_rate[%d]\n",
+ lavc_ctx->bit_rate, lavc_ctx->sample_rate);
+ } else {
+ mp_msg(MSGT_DECAUDIO,MSGL_V,
+ "lavc_ctx: bit_rate[%d] sample_rate[%d]\n"
+ "sh->avctx: bit_rate[%d] sample_rate[%d]\n",
+ lavc_ctx->bit_rate, lavc_ctx->sample_rate,
+ sh->avctx->bit_rate, sh->avctx->sample_rate);
+ }
+#endif
+ bps = lavc_ctx->bit_rate;
+ if (!bps)
+ if (sh->avctx)
+ if (sh->avctx->bit_rate)
+ bps = sh->avctx->bit_rate;
+ else
+ bps = 768000;
+ else
+ bps = 768000;
+ srate = lavc_ctx->sample_rate;
+ if (!srate)
+ if (sh->avctx)
+ if(sh->avctx->sample_rate)
+ srate = sh->avctx->sample_rate;
+ else
+ srate = 48000;
+ else
+ srate = 48000;
+ sh->channels = 2;
+ sh->i_bps = bps/8;
+ sh->sample_format = AF_FORMAT_IEC61937_LE;
switch (lavf_ctx->streams[0]->codec->codec_id) {
case CODEC_ID_AAC:
spdif_ctx->iec61937_packet_size = 16384;
- sh->sample_format = AF_FORMAT_IEC61937_LE;
sh->samplerate = srate;
- sh->channels = 2;
- sh->i_bps = bps;
break;
case CODEC_ID_AC3:
spdif_ctx->iec61937_packet_size = 6144;
- sh->sample_format = AF_FORMAT_IEC61937_LE;
sh->samplerate = srate;
- sh->channels = 2;
- sh->i_bps = bps;
break;
- case CODEC_ID_DTS: // FORCE USE DTS-HD
+ case CODEC_ID_DTS:
opt = av_opt_find(&lavf_ctx->oformat->priv_class,
"dtshd_rate", NULL, 0, 0);
if (!opt)
goto fail;
- dtshd_rate = (int*)(((uint8_t*)lavf_ctx->priv_data) +
- opt->offset);
- *dtshd_rate = 192000*4;
- spdif_ctx->iec61937_packet_size = 32768;
- sh->sample_format = AF_FORMAT_IEC61937_LE;
- sh->samplerate = 192000; // DTS core require 48000
- sh->channels = 2*4;
- sh->i_bps = bps;
+ dtshd_rate = (int*)(((uint8_t*)lavf_ctx->priv_data) + opt->offset);
+ switch (lavc_ctx->profile) {
+ case FF_PROFILE_DTS_HD_HRA:
+ *dtshd_rate = 192000;
+ spdif_ctx->iec61937_packet_size = 16384;
+ sh->samplerate = 192000;
+ break;
+ case FF_PROFILE_DTS_HD_MA:
+ *dtshd_rate = 768000;
+ spdif_ctx->iec61937_packet_size = 32768;
+ sh->samplerate = 192000;
+ sh->channels = 8;
+ break;
+ case FF_PROFILE_DTS:
+ case FF_PROFILE_DTS_ES:
+ case FF_PROFILE_DTS_96_24:
+ default:
+ *dtshd_rate = 0;
+ spdif_ctx->iec61937_packet_size = 8192;
+ sh->samplerate = 48000;
+ break;
+ }
break;
case CODEC_ID_EAC3:
spdif_ctx->iec61937_packet_size = 24576;
- sh->sample_format = AF_FORMAT_IEC61937_LE;
sh->samplerate = 192000;
- sh->channels = 2;
- sh->i_bps = bps;
break;
case CODEC_ID_MP3:
spdif_ctx->iec61937_packet_size = 4608;
sh->sample_format = AF_FORMAT_MPEG2;
sh->samplerate = srate;
- sh->channels = 2;
- sh->i_bps = bps;
break;
case CODEC_ID_TRUEHD:
+ switch (lavc_ctx->sample_rate) {
+ case 44100:
+ case 88200:
+ case 176400:
+ sh->samplerate = 176400;
+ break;
+ case 48000:
+ case 96000:
+ case 192000:
+ default:
+ sh->samplerate = 192000;
+ break;
+ }
spdif_ctx->iec61937_packet_size = 61440;
- sh->sample_format = AF_FORMAT_IEC61937_LE;
- sh->samplerate = 192000;
sh->channels = 8;
- sh->i_bps = bps;
break;
default:
break;
}
+ spdif_ctx->initialized = 1;
return 1;
fail:
@@ -229,7 +322,8 @@
AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx;
AVPacket pkt;
double pts;
- int ret, in_size, consumed, x;
+ int ret, in_size, consumed, x, y;
+ int len = maxlen;
unsigned char *start = NULL;
consumed = spdif_ctx->out_buffer_len = 0;
@@ -237,6 +331,14 @@
spdif_ctx->out_buffer = buf;
while (spdif_ctx->out_buffer_len + spdif_ctx->iec61937_packet_size < maxlen
&& spdif_ctx->out_buffer_len < minlen) {
+ if (spdif_ctx->init_buffer_len > 0 && spdif_ctx->initialized) {
+ x = write_packet(spdif_ctx,
+ &spdif_ctx->init_buffer[spdif_ctx->init_buffer_pos],
+ spdif_ctx->init_buffer_len);
+ spdif_ctx->init_buffer_pos += x;
+ spdif_ctx->init_buffer_len -= x;
+ continue;
+ }
if (sh->ds->eof)
break;
x = ds_get_packet_pts(sh->ds, &start, &pts);
@@ -267,11 +369,22 @@
sh->pts = pts;
sh->pts_bytes = 0;
}
+ if (!spdif_ctx->initialized){
+ y = avcodec_decode_audio3(spdif_ctx->lavc_ctx,
+ (int16_t*)buf, &len, &pkt);
+ if (y == AVERROR(EAGAIN))
+ continue;
+ if (lavf_ctx->oformat->write_packet(lavf_ctx, &pkt))
+ continue;
+ else
+ break;
+ }
ret = lavf_ctx->oformat->write_packet(lavf_ctx, &pkt);
if (ret < 0)
break;
}
- sh->pts_bytes += spdif_ctx->out_buffer_len;
+ if (spdif_ctx->initialized)
+ sh->pts_bytes += spdif_ctx->out_buffer_len;
return spdif_ctx->out_buffer_len;
}
@@ -293,7 +406,13 @@
{
struct spdifContext *spdif_ctx = sh->context;
AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx;
+ AVCodecContext *lavc_ctx = spdif_ctx->lavc_ctx;
+ if (lavc_ctx) {
+ avcodec_close(lavc_ctx);
+ av_freep(&lavc_ctx->extradata);
+ av_freep(&lavc_ctx);
+ }
if (lavf_ctx) {
if (lavf_ctx->oformat)
lavf_ctx->oformat->write_trailer(lavf_ctx);
Index: etc/codecs.conf
===================================================================
--- etc/codecs.conf (revision 34655)
+++ etc/codecs.conf (working copy)
@@ -5555,7 +5555,7 @@
fourcc ".mp1" ; MP1 (MOV files)
fourcc "MP3 " ; used in .nsv files
fourcc "LAME" ; used in mythtv .nuv files
- dll mpa
+ dll mp3
driver spdif
audiocodec spdifthd
@@ -5563,7 +5563,7 @@
status working
comment "needs -channels 8"
fourcc TRHD ; internal MPlayer FourCC
- dll thd
+ dll truehd
driver spdif
audiocodec ffwavesynth
_______________________________________________
MPlayer-dev-eng mailing list
MPlayer-dev-eng@mplayerhq.hu
https://lists.mplayerhq.hu/mailman/listinfo/mplayer-dev-eng
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic