For those following the AC3 audio saga, here is a patch against the CVS from 
yesterday to get AC3 audio up and running with DVB. This patch is different 
to previous patches in a number of ways, mostly I have changed things after 
advice from Isaac.

Notes:

1. There is no longer a GUI option for Dolby Audio, I agree with Isaac that it 
is not needed. This simplifies the patch greatly.

2. There is finally what I regard as a good fix for the mpeg "ghost" audio 
track problem. I have added a call to av_remove_stream in SeekReset in 
avformat decoder. This clears all streams from mpeg.c whenever channels 
change. There is still a chance for "ghost" tracks when a station changes the 
available audio tracks whilst you are watching. 

3. I have changed the algorithm in autoSelectAudio track. The original 
function (what is in CVS now)  selects the first audio track that has at 
least minchannels channels, where minchannels was 2 for ac3passthru and 1 
otherwise. I have changed the algorithm to choose the first ac3 track it 
finds, or if no ac3 is found then it chooses the audio track with the highest 
number of channels. 

This could possibly be enhanced to honour language settings and check sample 
rate as well.

4. The ChackAudioParams change has been replaced with strategic calls to 
SetupAudioStream() in inc,dec,setCurrentAudioTrack and autoSelectAudioTrack. 
This seems to fix the audio initialisation problems, although occasionaly 
when I change from a station with ac3 to one without I get no audio, this is 
quite rare but still needs to be investigated.

Cheers,
Mark Anderson
Index: libs/libmythtv/avformatdecoder.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/avformatdecoder.cpp,v
retrieving revision 1.131
diff -b -u -p -r1.131 avformatdecoder.cpp
--- libs/libmythtv/avformatdecoder.cpp	29 Jan 2005 00:06:57 -0000	1.131
+++ libs/libmythtv/avformatdecoder.cpp	29 Jan 2005 01:49:18 -0000
@@ -249,6 +249,10 @@ void AvFormatDecoder::SeekReset(long lon
             break;
         skipFrames--;
     }
+    for (int i = ic->nb_streams - 1; i >= 0; i--)
+    {
+        av_remove_stream(ic, ic->streams[i]->id);
+    }
 }
 
 void AvFormatDecoder::Reset(void)
@@ -1140,6 +1144,7 @@ void AvFormatDecoder::incCurrentAudioTra
         wantedAudioStream = audioStreams[currentAudioTrack];
 
         AVCodecContext *e = &ic->streams[wantedAudioStream]->codec;
+        SetupAudioStream();
         CheckAudioParams(e->sample_rate, e->channels, true);
     }
 }
@@ -1157,6 +1162,7 @@ void AvFormatDecoder::decCurrentAudioTra
         wantedAudioStream = audioStreams[currentAudioTrack];
 
         AVCodecContext *e = &ic->streams[wantedAudioStream]->codec;
+        SetupAudioStream();
         CheckAudioParams(e->sample_rate, e->channels, true);
     }
 }
@@ -1175,10 +1181,23 @@ bool AvFormatDecoder::setCurrentAudioTra
     wantedAudioStream = audioStreams[currentAudioTrack];
 
     AVCodecContext *e = &ic->streams[wantedAudioStream]->codec;
+    SetupAudioStream();
     CheckAudioParams(e->sample_rate, e->channels, true);
     return true;
 }
 
+//
+// This function will select the best audio track
+// available usgin the following rules:
+//
+// 1. The fist AC3 track found will be select,
+// 2. If no AC3 is found then the audio track with
+// the most number of channels is selected. 
+//
+// This code has no awareness to language preferences
+// although I don't think it would be too hard to 
+// add.
+//
 bool AvFormatDecoder::autoSelectAudioTrack()
 {
     if (!audioStreams.size())
@@ -1191,7 +1210,10 @@ bool AvFormatDecoder::autoSelectAudioTra
     if (do_ac3_passthru)
         minChannels = 2;
 
-    while (!foundAudio)
+    int selectedTrack = -1;
+    int selectedChannels = -1;
+    
+    while ((!foundAudio) && (minChannels >= 0))
     {
         for (track = maxTracks; track >= 0; track--)
         {
@@ -1200,26 +1222,58 @@ bool AvFormatDecoder::autoSelectAudioTra
 
             if (e->channels > minChannels)
             {
-                currentAudioTrack = track;
-                wantedAudioStream = tempStream;
-                VERBOSE(VB_AUDIO, 
-                        QString("Auto-selecting audio track #%1 (stream #%2).")
-                               .arg(track + 1).arg(tempStream));
-                VERBOSE(VB_AUDIO, 
-                        QString("It has %1 channels and we needed at least %2")
-                               .arg(e->channels).arg(minChannels + 1));
+                //if we find an AC3 codec then we select it 
+                //as the preferred codec.
+                if (e->codec_id == CODEC_ID_AC3)
+                {
+                    selectedTrack = track;
+                    foundAudio = true;
+                    break;
+                }
 
-                AVCodecContext *e = &ic->streams[wantedAudioStream]->codec;
-                CheckAudioParams(e->sample_rate, e->channels, true);
-                return true;
+                if (e->channels > selectedChannels)
+                {
+                    //this is a candidate with more channels
+                    //than the previous, or there was no previous
+                    //so select it.
+                    selectedTrack = track;
+                }
             }
         }
+        if (!foundAudio)
+        {
         minChannels--;
-        if (minChannels < 0)
-            return false;
+        }
     }
 
+    if (selectedTrack == -1)
+    {
+        //no suitable track was found
     return false;
+    }
+
+    currentAudioTrack = selectedTrack;
+    wantedAudioStream = audioStreams[currentAudioTrack];
+     
+    AVCodecContext *e = &ic->streams[wantedAudioStream]->codec;
+    if (e->codec_id == CODEC_ID_AC3)
+    {
+        VERBOSE(VB_AUDIO, 
+                QString("Auto-selecting AC3 audio track (stream #%2).")
+                .arg(wantedAudioStream)); 
+    }
+    else
+    {
+        VERBOSE(VB_AUDIO, 
+                QString("Auto-selecting audio track #%1 (stream #%2).")
+                .arg(selectedTrack + 1).arg(wantedAudioStream));
+        VERBOSE(VB_AUDIO, 
+                QString("It has %1 channels and we needed at least %2")
+                .arg(selectedChannels).arg(minChannels + 1));
+    }
+    SetupAudioStream();
+    CheckAudioParams(e->sample_rate, e->channels, true);
+    return true;
 }
 
 void AvFormatDecoder::SetupAudioStream(void)
Index: libs/libmythtv/sitypes.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/sitypes.cpp,v
retrieving revision 1.3
diff -b -u -p -r1.3 sitypes.cpp
--- libs/libmythtv/sitypes.cpp	26 Jan 2005 05:54:05 -0000	1.3
+++ libs/libmythtv/sitypes.cpp	29 Jan 2005 01:49:20 -0000
@@ -296,7 +296,7 @@ ElementaryPIDObject *PMTObject::Preferre
     QValueList<ElementaryPIDObject>::Iterator pit;
 
     // Change this if you prefer AC3
-    bool prefer_ac3 = false;
+    bool prefer_ac3 = true;
     if (prefer_ac3)
     {
         for (pit = Components.begin(); pit != Components.end(); ++pit)
_______________________________________________
mythtv-dev mailing list
[email protected]
http://mythtv.org/cgi-bin/mailman/listinfo/mythtv-dev

Reply via email to