[MPlayer-dev-eng] [PATCH] AVParser for audio support
Reimar Döffinger
Reimar.Doeffinger at gmx.de
Wed Aug 26 19:42:31 CEST 2009
Hello,
probably quite some room for improvements, though I think it is a good
step forward even if it is still a bit ugly.
It allows to use ffdca and ffac3 with the native AVI and MPEG demuxers.
-------------- next part --------------
Index: libmpdemux/demux_ts.c
===================================================================
--- libmpdemux/demux_ts.c (revision 29551)
+++ libmpdemux/demux_ts.c (working copy)
@@ -305,6 +305,7 @@
if(sh)
{
const char *lang = pid_lang_from_pmt(priv, es->pid);
+ sh->needs_parsing = 1;
sh->format = IS_AUDIO(es->type) ? es->type : es->subtype;
sh->ds = demuxer->audio;
Index: libmpdemux/demux_mpg.c
===================================================================
--- libmpdemux/demux_mpg.c (revision 29551)
+++ libmpdemux/demux_mpg.c (working copy)
@@ -270,6 +270,7 @@
sh_audio_t* sh_a;
new_sh_audio(demux,aid);
sh_a = (sh_audio_t*)demux->a_streams[aid];
+ sh_a->needs_parsing = 1;
switch(aid & 0xE0){ // 1110 0000 b (high 3 bit: type low 5: id)
case 0x00: sh_a->format=0x50;break; // mpeg
case 0xA0: sh_a->format=0x10001;break; // dvd pcm
Index: libmpdemux/stheader.h
===================================================================
--- libmpdemux/stheader.h (revision 29551)
+++ libmpdemux/stheader.h (working copy)
@@ -32,6 +32,10 @@
unsigned int format;
int initialized;
float stream_delay; // number of seconds stream should be delayed (according to dwStart or similar)
+ // things needed for parsing
+ int needs_parsing;
+ struct AVCodecContext *avctx;
+ struct AVCodecParserContext *parser;
// output format:
int sample_format;
int samplerate;
Index: libmpdemux/demuxer.c
===================================================================
--- libmpdemux/demuxer.c (revision 29551)
+++ libmpdemux/demuxer.c (working copy)
@@ -330,6 +330,10 @@
free(sh->wf);
free(sh->codecdata);
free(sh->lang);
+#ifdef CONFIG_LIBAVCODEC
+ av_parser_close(sh->parser);
+ av_freep(&sh->avctx);
+#endif
free(sh);
}
@@ -409,7 +413,7 @@
}
-void ds_add_packet(demux_stream_t *ds, demux_packet_t *dp)
+static void ds_add_packet_internal(demux_stream_t *ds, demux_packet_t *dp)
{
// append packet to DS stream:
++ds->packs;
@@ -429,6 +433,65 @@
ds->demuxer->video->packs);
}
+void ds_add_packet(demux_stream_t *ds, demux_packet_t *dp)
+{
+#ifdef CONFIG_LIBAVCODEC
+ AVCodecParserContext *parser = NULL;
+ AVCodecContext *avctx = NULL;
+ if (ds == ds->demuxer->audio) {
+ sh_audio_t *sh = ds->sh;
+ if (!sh->parser && sh->needs_parsing) {
+ enum CodecID codec_id = CODEC_ID_NONE;
+ extern int avcodec_initialized;
+ if (!avcodec_initialized) {
+ avcodec_init();
+ avcodec_register_all();
+ avcodec_initialized = 1;
+ }
+ switch (sh->format) {
+ case 0x2000:
+ case 0x332D6361:
+ case 0x332D4341:
+ case MKTAG('d', 'n', 'e', 't'):
+ case MKTAG('s', 'a', 'c', '3'):
+ codec_id = CODEC_ID_AC3;
+ break;
+ case MKTAG('E', 'A', 'C', '3'):
+ codec_id = CODEC_ID_EAC3;
+ break;
+ case 0x2001:
+ case 0x86:
+ codec_id = CODEC_ID_DTS;
+ break;
+ }
+ if (codec_id != CODEC_ID_NONE) {
+ sh->avctx = avcodec_alloc_context();
+ sh->parser = av_parser_init(codec_id);
+ }
+ }
+ parser = sh->parser;
+ avctx = sh->avctx;
+ }
+ if (parser) {
+ int len = dp->len;
+ int pos = 0;
+ while (len > 0) {
+ demux_packet_t *dp2;
+ uint8_t *parsed_start = dp->buffer + pos;
+ int parsed_len = len;
+ int consumed = av_parser_parse2(parser, avctx, &parsed_start, &parsed_len,
+ dp->buffer + pos, len, dp->pts, dp->pts, dp->pos);
+ pos += consumed;
+ len -= consumed;
+ dp2 = new_demux_packet(parsed_len);
+ memcpy(dp2->buffer, parsed_start, parsed_len);
+ ds_add_packet_internal(ds, dp2);
+ }
+ } else
+#endif
+ ds_add_packet_internal(ds, dp);
+}
+
void ds_read_packet(demux_stream_t *ds, stream_t *stream, int len,
double pts, off_t pos, int flags)
{
Index: libmpdemux/demux_avi.c
===================================================================
--- libmpdemux/demux_avi.c (revision 29551)
+++ libmpdemux/demux_avi.c (working copy)
@@ -60,6 +60,7 @@
sh_audio_t* sh;
avi_priv_t *priv=demux->priv;
sh=demux->audio->sh=demux->a_streams[stream_id];
+ sh->needs_parsing = 1;
mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected AVI audio ID = %d\n",demux->audio->id);
if(sh->wf){
priv->audio_block_size=sh->wf->nBlockAlign;
More information about the MPlayer-dev-eng
mailing list