Ticket #2439: 2439-v2.patch

File 2439-v2.patch, 10.6 KB (added by szermatt, 13 years ago)

2439-v2.patch

  • libs/libmythtv/avformatdecoder.cpp

     
    14881488                lang_indx = lang_aud_cnt[lang];
    14891489                lang_aud_cnt[lang]++;
    14901490            }
    1491             tracks[kTrackTypeAudio].push_back(
    1492                 StreamInfo(i, lang, lang_indx, ic->streams[i]->id));
    14931491
     1492            if (ic->streams[i]->codec->avcodec_dual_language)
     1493            {
     1494                tracks[kTrackTypeAudio].push_back(
     1495                    StreamInfo(i, lang, lang_indx, ic->streams[i]->id, 0));
     1496                tracks[kTrackTypeAudio].push_back(
     1497                    StreamInfo(i, lang, lang_indx, ic->streams[i]->id, 1));
     1498            }
     1499            else
     1500            {
     1501                tracks[kTrackTypeAudio].push_back(
     1502                    StreamInfo(i, lang, lang_indx, ic->streams[i]->id));
     1503            }
     1504
    14941505            VERBOSE(VB_AUDIO, LOC + QString(
    14951506                        "Audio Track #%1 is A/V stream #%2 "
    14961507                        "and has %3 channels in the %4 language(%5).")
     
    15551566    return scanerror;
    15561567}
    15571568
     1569/** \fn AvFormatDecoder::SetupAudioStreamSubIndexes(bool, bool)
     1570 *  \brief Reacts to DUAL/STEREO changes on the fly and fix streams.
     1571 *
     1572 *  This function should be called when a switch between dual and
     1573 *  stereo mpeg audio is detected. Such changes can and will happen at
     1574 *  any time.
     1575 *
     1576 *  After this method returns, a new audio stream should be selected
     1577 *  using AvFormatDecoder::autoSelectSubtitleTrack().
     1578 *
     1579 *  \param index av_stream_index of the stream that has changed
     1580 */
     1581void AvFormatDecoder::SetupAudioStreamSubIndexes(int streamIndex)
     1582{
     1583    QMutexLocker locker(&avcodeclock);
     1584
     1585    // Find the position of the streaminfo in tracks[kTrackTypeAudio]
     1586    sinfo_vec_t::iterator current = tracks[kTrackTypeAudio].begin();
     1587    for (; current != tracks[kTrackTypeAudio].end(); ++current)
     1588    {
     1589        if (current->av_stream_index == streamIndex)
     1590            break;
     1591    }
     1592    if (current == tracks[kTrackTypeAudio].end()) {
     1593        VERBOSE(VB_IMPORTANT, LOC
     1594                <<"Warning: invalid stream index passed to "
     1595                <<"SetupAudioStreamSubIndexes: "
     1596                <<streamIndex);
     1597        return;
     1598    }
     1599
     1600    // Remove the extra substream or duplicate the current substream
     1601    sinfo_vec_t::iterator next = current + 1;
     1602    if (current->av_substream_index == -1) {
     1603        // Split stream in two (Language I + Language II)
     1604        StreamInfo lang1 = *current;
     1605        StreamInfo lang2 = *current;
     1606        lang1.av_substream_index = 0;
     1607        lang2.av_substream_index = 1;
     1608        *current = lang1;
     1609        tracks[kTrackTypeAudio].insert(next, lang2);
     1610    }
     1611    else
     1612    {
     1613        if (next == tracks[kTrackTypeAudio].end() ||
     1614            next->av_stream_index != streamIndex) {
     1615            VERBOSE(VB_IMPORTANT, LOC
     1616                    <<"Warning: expected substream 1 (Language I) of stream "
     1617                    << streamIndex
     1618                    << " following substream 0, found end of list or another stream");
     1619            return;
     1620        }
     1621
     1622        // Remove extra stream info
     1623        StreamInfo stream = *current;
     1624        stream.av_substream_index = -1;
     1625        *current = stream;
     1626        tracks[kTrackTypeAudio].erase(next);
     1627    }
     1628}
     1629
    15581630int get_avf_buffer(struct AVCodecContext *c, AVFrame *pic)
    15591631{
    15601632    AvFormatDecoder *nd = (AvFormatDecoder *)(c->opaque);
     
    23682440 *   preference:
    23692441 *
    23702442 *   1) The stream last selected by the user, which is
    2371  *      recalled as the Nth stream in the preferred language.
     2443 *      recalled as the Nth stream in the preferred language
     2444 *      or the Nth substream when audio is in dual language
     2445 *      format (each channel contains a different language track)
    23722446 *      If it can not be located we attempt to find a stream
    23732447 *      in the same language.
    23742448 *
     
    24352509    int selTrack = (1 == numStreams) ? 0 : -1;
    24362510    int wlang    = wtrack.language;
    24372511
     2512    if (selTrack < 0 && wtrack.av_substream_index >= 0)
     2513    {
     2514        VERBOSE(VB_AUDIO, LOC + "Trying to reselect audio sub-stream");
     2515        // Dual stream without language information: choose
     2516        // the previous substream that was kept in wtrack,
     2517        // ignoring the stream index (which might have changed).
     2518        int substream_index = wtrack.av_substream_index;
     2519
     2520        for (uint i = 0; i < numStreams; i++)
     2521        {
     2522            if (atracks[i].av_substream_index == substream_index)
     2523            {
     2524                selTrack = i;
     2525                break;
     2526            }
     2527        }
     2528    }
     2529
    24382530    if ((selTrack < 0) && wlang >= -1 && numStreams)
    24392531    {
    24402532        VERBOSE(VB_AUDIO, LOC + "Trying to reselect audio track");
     
    25152607    return selTrack;
    25162608}
    25172609
     2610static void filter_audio_data(int channel, AudioInfo *audioInfo,
     2611                              char *buffer, int bufsize)
     2612{
     2613    // Only stereo -> mono (left or right) is supported
     2614    if (audioInfo->channels != 2)
     2615        return;
     2616
     2617    if (channel != 0 && channel != 1)
     2618        return;
     2619
     2620    const int samplesize = audioInfo->sample_size;
     2621    const int samples = bufsize / samplesize;
     2622    const int halfsample = samplesize/2;
     2623
     2624    const char *from;
     2625    char *to;
     2626
     2627    if (channel==0)
     2628    {
     2629        from = buffer;
     2630        to = buffer + halfsample;
     2631    }
     2632    else
     2633    {
     2634        from = buffer + halfsample;
     2635        to = buffer;
     2636    }
     2637
     2638    for (int sample = 0; sample < samples;
     2639         (sample++), (from += samplesize), (to += samplesize))
     2640    {
     2641        for(int bit = 0; bit < halfsample; bit++)
     2642            to[bit] = from[bit];
     2643    }
     2644}
     2645
    25182646bool AvFormatDecoder::GetFrame(int onlyvideo)
    25192647{
    25202648    AVPacket *pkt = NULL;
     
    27832911        avcodeclock.lock();
    27842912        int ctype  = curstream->codec->codec_type;
    27852913        int audIdx = selectedTrack[kTrackTypeAudio].av_stream_index;
     2914        int audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index;
    27862915        int subIdx = selectedTrack[kTrackTypeSubtitle].av_stream_index;
    27872916        avcodeclock.unlock();
    27882917
     
    27922921            {
    27932922                case CODEC_TYPE_AUDIO:
    27942923                {
     2924                    bool reselectAudioTrack = false;
     2925
     2926                    // detect switches between stereo and dual languages
     2927                    bool wasDual = audSubIdx != -1;
     2928                    bool isDual = curstream->codec->avcodec_dual_language;
     2929                    if ((wasDual && !isDual) || (!wasDual &&  isDual))
     2930                    {
     2931                        SetupAudioStreamSubIndexes(audIdx);
     2932                        reselectAudioTrack = true;
     2933                    }                           
     2934
    27952935                    // detect channels on streams that need
    27962936                    // to be decoded before we can know this
    27972937                    if (!curstream->codec->channels)
     
    28012941                        ret = avcodec_decode_audio(
    28022942                            curstream->codec, audioSamples,
    28032943                            &data_size, ptr, len);
    2804                         if (curstream->codec->channels)
    2805                         {
    2806                             currentTrack[kTrackTypeAudio] = -1;
    2807                             selectedTrack[kTrackTypeAudio]
    2808                                 .av_stream_index = -1;
    2809                             audIdx = -1;
    2810                             AutoSelectAudioTrack();
    2811                             audIdx = selectedTrack[kTrackTypeAudio]
    2812                                 .av_stream_index;
    2813                         }
     2944
     2945                        reselectAudioTrack |= curstream->codec->channels;
    28142946                    }
    28152947
     2948                    if (reselectAudioTrack)
     2949                    {
     2950                        QMutexLocker locker(&avcodeclock);
     2951                        currentTrack[kTrackTypeAudio] = -1;
     2952                        selectedTrack[kTrackTypeAudio]
     2953                            .av_stream_index = -1;
     2954                        audIdx = -1;
     2955                        audSubIdx = -1;
     2956                        AutoSelectAudioTrack();
     2957                        audIdx = selectedTrack[kTrackTypeAudio]
     2958                            .av_stream_index;
     2959                        audSubIdx = selectedTrack[kTrackTypeAudio]
     2960                            .av_substream_index;
     2961                    }
     2962
    28162963                    if (firstloop && pkt->pts != (int64_t)AV_NOPTS_VALUE)
    28172964                        lastapts = (long long)(av_q2d(curstream->time_base) *
    28182965                                               pkt->pts * 1000);
     
    28953042                            .arg(pkt->pts).arg(pkt->dts).arg(temppts)
    28963043                                                        .arg(lastapts));
    28973044
     3045                    if (audSubIdx != -1)
     3046                    {
     3047                        filter_audio_data(audSubIdx, &audioOut,
     3048                                          (char *)audioSamples, data_size);
     3049                    }
     3050
    28983051                    GetNVP()->AddAudioData((char *)audioSamples, data_size,
    28993052                                           temppts);
    29003053
  • libs/libmythtv/decoderbase.h

     
    1717class StreamInfo
    1818{
    1919  public:
    20     StreamInfo() : av_stream_index(-1), language(-2), language_index(0),
     20    StreamInfo() :
     21        av_stream_index(-1), av_substream_index(-1),
     22        language(-2), language_index(0),
    2123        stream_id(-1), easy_reader(false), wide_aspect_ratio(false) {}
    2224    StreamInfo(int a, int b, uint c, int d, bool e = false, bool f = false) :
    23         av_stream_index(a), language(b), language_index(c), stream_id(d),
     25        av_stream_index(a), av_substream_index(-1),
     26        language(b), language_index(c), stream_id(d),
    2427        easy_reader(e), wide_aspect_ratio(f) {}
     28    StreamInfo(int a, int b, uint c, int d, int e,
     29               bool f = false, bool g = false) :
     30        av_stream_index(a), av_substream_index(e),
     31        language(b), language_index(c), stream_id(d),
     32        easy_reader(f), wide_aspect_ratio(g) {}
    2533
    2634  public:
    2735    int  av_stream_index;
     36    // -1 = no substream, 0 for first dual audio stream, 1 for second
     37    int  av_substream_index;
    2838    int  language; ///< ISO639 canonical language key
    2939    uint language_index;
    3040    int  stream_id;
  • libs/libmythtv/avformatdecoder.h

     
    185185    void SeekReset(long long, uint skipFrames, bool doFlush, bool discardFrames);
    186186
    187187    bool SetupAudioStream(void);
     188    void SetupAudioStreamSubIndexes(int streamIndex);
    188189
    189190    /// Update our position map, keyframe distance, and the like.
    190191    /// Called for key frame packets.