2012-01-03 6 views
1

Я новичок в ffmpeg. У меня проблема, когда на некоторых носителях есть несколько аудиопотоков. Пусть в MKV файл, он имеет три звуковые потоки (MP3, WMA и WMAPro)Как изменить индекс потока в libavformat

Как изменить индекс потока при демультиплексировании с помощью:

AVPacket inputPacket; 
ret = av_read_frame(avInputFmtCtx, &inputPacket) 

Так я ищу что-то вроде change_stream_index (ИНТ streamindex), и когда я вызываю эту функцию (предположим change_stream_index (2)), следующий вызов av_read_frame будет использовать demux WMAPro вместо MP3.

Спасибо, ребята!

ответ

0

Ну, сначала вы проверяете количество потоков на входе. Тогда вы пишете их в некотором буфере (в моем случае, у меня есть только 2 потока, но вы можете легко расширить это)

ptrFormatContext = avformat_alloc_context(); 

    if(avformat_open_input(&ptrFormatContext, filename, NULL, NULL) != 0) 
    { 
     qDebug("Error opening the input"); 
     exit(-1); 
    } 
    if(av_find_stream_info(ptrFormatContext) < 0) 
    { 
     qDebug("Could not find any stream info"); 
     exit(-2); 
    } 
    dump_format(ptrFormatContext, 0, filename, (int) NULL); 

    for(i=0; i<ptrFormatContext->nb_streams; i++) 
    { 
     switch(ptrFormatContext->streams[i]->codec->codec_type) 
     { 
     case AVMEDIA_TYPE_VIDEO: 
     { 
      if(videoStream < 0) videoStream = i; 
      break; 
     } 
     case AVMEDIA_TYPE_AUDIO: 
     { 
      if(audioStream < 0) audioStream = i; 
     } 
     } 
    } 
    if(audioStream == -1) 
    { 
     qDebug("Could not find any audio stream"); 
     exit(-3); 
    } 
    if(videoStream == -1) 
    { 
     qDebug("Could not find any video stream"); 
     exit(-4); 
    } 

Поскольку вы не знаете, в каком порядке потоки приходят, вы также будете иметь для проверки имени кодека: ptrFormatContext->streams[i]->codec->codec_name, а затем сохраните индекс для соответствующего target_format. Тогда вы можете просто получить доступ поток через данный индекс:

while(av_read_frame(ptrFormatContext,&ptrPacket) >= 0) 
    { 
     if(ptrPacket.stream_index == videoStream) 
     { 
      //decode the video stream to raw format 
      if(avcodec_decode_video2(ptrCodecCtxt, ptrFrame, &frameFinished, &ptrPacket) < 0) 
      { 
       qDebug("Error decoding the Videostream"); 
       exit(-13); 
      } 
      if(frameFinished) 
      { 
       printf("%s\n", (char*) ptrPacket.data); 
//encode the video stream to target format 
//    av_free_packet(&ptrPacket); 
      } 
     } 
     else if (ptrPacket.stream_index == audioStream) 
     { 
      //decode the audio stream to raw format 
//   if(avcodec_decode_audio3(aCodecCtx, , ,&ptrPacket) < 0) 
//   { 
//    qDebug("Error decoding the Audiostream"); 
//    exit(-14); 
//   } 
      //encode the audio stream to target format 
     } 
    } 

Я просто скопировал некоторые выдержки из программы шахты, но это будет, мы надеемся, поможет вам понять, как выбрать потоки от входа. Я не публиковал полный код, только выдержки, поэтому вам придется выполнять инициализацию и т. Д. Самостоятельно, но если у вас есть какие-либо вопросы, я с радостью поможем вам!

Смежные вопросы