2013-07-11 6 views
7

Ich habe dieses ffmpeg BefehlFFMpeg - Wie Codec (Video und Audio) kopieren von 'mp4' Container 'ts' Container

ffmpeg -ic: \ input.mp4 -vcodec kopieren -acodec copy - vbsf h264_mp4toannexb c: \ Ausgabe.ts.

Der obige Befehl konvertiert input.mp4 erfolgreich in output.ts.

Ich muss die gleiche Funktionalität über Code implementieren (mit der ffmpeg-Bibliothek).

Weiß jemand, wie man ohne Dekodierung und Kodierung von einem Container in einen anderen kopiert?

+0

Danke für die Frage :) –

Antwort

13

Wenn Sie nur für Stream-Kopie suchen, können Sie dies ganz einfach tun. Sie können die folgenden Schritte beziehen.

//1. Do initialization using 

    av_register_all(); 

// 2. Open input file using 

    avformat_open_input(&m_informat, filename.c_str(), 0, 0)); 

//3. Find input stream info. 

    if ((ret = avformat_find_stream_info(m_informat, 0))< 0) 
     { 
      av_strerror(ret,errbuf,sizeof(errbuf)); 
      PRINT_VAL("Not Able to find stream info:: ", errbuf) 
      ret = -1; 
      return ret; 
     } 

     for (unsigned int i = 0; i<m_informat->nb_streams; i++) 
     { 
      if(m_informat->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) 
      { 
       PRINT_MSG("Found Video Stream ") 
       m_in_vid_strm_idx = i; 
       m_in_vid_strm = m_informat->streams[i]; 
      } 

     if(m_informat->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) 
     { 
      m_in_aud_strm_idx = i; 
      m_in_aud_strm = m_informat->streams[i]; 
     } 


// 4. Create ouputfile and allocate output format. 

    AVOutputFormat *outfmt = NULL; 
    std::string outfile = std::string(filename) + "clip_out.ts"; 
     outfmt = av_guess_format(NULL,outfile.c_str(),NULL); 
    if(outfmt == NULL) 
     { 
      ret = -1; 
      return ret; 
     } 
     else 
     { 
      m_outformat = avformat_alloc_context(); 
      if(m_outformat) 
      { 
       m_outformat->oformat = outfmt; 
       _snprintf(m_outformat->filename, 
       sizeof(m_outformat->filename), "%s", outfile.c_str());  
      } 
      else 
      { 
       ret = -1; 
       return ret; 
      } 
     } 

//5. Add audio and video stream to output format. 

     AVCodec *out_vid_codec,*out_aud_codec; 
     out_vid_codec = out_aud_codec = NULL; 

     if(outfmt->video_codec != AV_CODEC_ID_NONE && m_in_vid_strm != NULL) 
     { 
      out_vid_codec = avcodec_find_encoder(outfmt->video_codec); 
      if(NULL == out_vid_codec) 
      { 
       PRINT_MSG("Could Not Find Vid Encoder") 
       ret = -1; 
       return ret; 
      } 
      else 
      { 
       PRINT_MSG("Found Out Vid Encoder ") 
       m_out_vid_strm = avformat_new_stream(m_outformat, out_vid_codec); 
       if(NULL == m_out_vid_strm) 
       { 
        PRINT_MSG("Failed to Allocate Output Vid Strm ") 
        ret = -1; 
        return ret; 
       } 
       else 
       { 
        PRINT_MSG("Allocated Video Stream ") 
        if(avcodec_copy_context(m_out_vid_strm->codec, 
         m_informat->streams[m_in_vid_strm_idx]->codec) != 0) 
        { 
         PRINT_MSG("Failed to Copy Context ") 
         ret = -1; 
         return ret; 
        } 
        else 
        { 
         m_out_vid_strm->sample_aspect_ratio.den = 
         m_out_vid_strm->codec->sample_aspect_ratio.den; 

         m_out_vid_strm->sample_aspect_ratio.num = 
         m_in_vid_strm->codec->sample_aspect_ratio.num; 
         PRINT_MSG("Copied Context ") 
         m_out_vid_strm->codec->codec_id = m_in_vid_strm->codec->codec_id; 
         m_out_vid_strm->codec->time_base.num = 1; 
         m_out_vid_strm->codec->time_base.den = 
         m_fps*(m_in_vid_strm->codec->ticks_per_frame);   
         m_out_vid_strm->time_base.num = 1; 
         m_out_vid_strm->time_base.den = 1000; 
         m_out_vid_strm->r_frame_rate.num = m_fps; 
         m_out_vid_strm->r_frame_rate.den = 1; 
         m_out_vid_strm->avg_frame_rate.den = 1; 
         m_out_vid_strm->avg_frame_rate.num = m_fps; 
         m_out_vid_strm->duration = (m_out_end_time - m_out_start_time)*1000; 
        } 
        } 
       } 
      } 

     if(outfmt->audio_codec != AV_CODEC_ID_NONE && m_in_aud_strm != NULL) 
     { 
      out_aud_codec = avcodec_find_encoder(outfmt->audio_codec); 
      if(NULL == out_aud_codec) 
      { 
       PRINT_MSG("Could Not Find Out Aud Encoder ") 
       ret = -1; 
       return ret; 
      } 
      else 
      { 
       PRINT_MSG("Found Out Aud Encoder ") 
       m_out_aud_strm = avformat_new_stream(m_outformat, out_aud_codec); 
       if(NULL == m_out_aud_strm) 
       { 
        PRINT_MSG("Failed to Allocate Out Vid Strm ") 
        ret = -1; 
        return ret; 
       } 
       else 
       { 
        if(avcodec_copy_context(m_out_aud_strm->codec, 
         m_informat->streams[m_in_aud_strm_idx]->codec) != 0) 
        { 
         PRINT_MSG("Failed to Copy Context ") 
         ret = -1; 
         return ret; 
        } 
        else 
        { 
         PRINT_MSG("Copied Context ") 
         m_out_aud_strm->codec->codec_id = m_in_aud_strm->codec->codec_id; 
         m_out_aud_strm->codec->codec_tag = 0; 
         m_out_aud_strm->pts = m_in_aud_strm->pts; 
         m_out_aud_strm->duration = m_in_aud_strm->duration; 
         m_out_aud_strm->time_base.num = m_in_aud_strm->time_base.num; 
         m_out_aud_strm->time_base.den = m_in_aud_strm->time_base.den; 

        } 
       } 
      } 
      } 
// 6. Finally output header. 
     if (!(outfmt->flags & AVFMT_NOFILE)) 
      { 
      if (avio_open2(&m_outformat->pb, outfile.c_str(), AVIO_FLAG_WRITE,NULL, NULL) < 0) 
      { 
        PRINT_VAL("Could Not Open File ", outfile) 
        ret = -1; 
        return ret; 
      } 
      } 
      /* Write the stream header, if any. */ 
      if (avformat_write_header(m_outformat, NULL) < 0) 
      { 
       PRINT_VAL("Error Occurred While Writing Header ", outfile) 
       ret = -1; 
       return ret; 
      } 
      else 
      { 
       PRINT_MSG("Written Output header ") 
       m_init_done = true; 
      } 

// 7. Now in while loop read frame using av_read_frame and write to output format using 
// av_interleaved_write_frame(). You can use following loop 

     while(av_read_frame(m_informat, &pkt) >= 0 && (m_num_frames-- > 0)) 
      { 
       if(pkt.stream_index == m_in_vid_strm_idx) 
       { 
        PRINT_VAL("ACTUAL VID Pkt PTS ",av_rescale_q(pkt.pts,m_in_vid_strm->time_base, m_in_vid_strm->codec->time_base)) 
        PRINT_VAL("ACTUAL VID Pkt DTS ", av_rescale_q(pkt.dts, m_in_vid_strm->time_base, m_in_vid_strm->codec->time_base)) 
        av_init_packet(&outpkt); 
        if(pkt.pts != AV_NOPTS_VALUE) 
        { 
         if(last_vid_pts == vid_pts) 
         { 
          vid_pts++; 
          last_vid_pts = vid_pts; 
         } 
         outpkt.pts = vid_pts; 
         PRINT_VAL("ReScaled VID Pts ", outpkt.pts) 
        } 
        else 
        { 
         outpkt.pts = AV_NOPTS_VALUE; 
        } 

        if(pkt.dts == AV_NOPTS_VALUE) 
        { 
         outpkt.dts = AV_NOPTS_VALUE; 
        } 
        else 
        { 
         outpkt.dts = vid_pts; 
         PRINT_VAL("ReScaled VID Dts ", outpkt.dts) 
         PRINT_MSG("=======================================") 
        } 

        outpkt.data = pkt.data; 
        outpkt.size = pkt.size; 
        outpkt.stream_index = pkt.stream_index; 
        outpkt.flags |= AV_PKT_FLAG_KEY; 
        last_vid_pts = vid_pts; 
        if(av_interleaved_write_frame(m_outformat, &outpkt) < 0) 
        { 
         PRINT_MSG("Failed Video Write ") 
        } 
        else 
        { 
         m_out_vid_strm->codec->frame_number++; 
        } 
        av_free_packet(&outpkt); 
        av_free_packet(&pkt); 
       } 
       else if(pkt.stream_index == m_in_aud_strm_idx) 
       { 
        PRINT_VAL("ACTUAL AUD Pkt PTS ", av_rescale_q(pkt.pts, m_in_aud_strm->time_base, m_in_aud_strm->codec->time_base)) 
        PRINT_VAL("ACTUAL AUD Pkt DTS ", av_rescale_q(pkt.dts, m_in_aud_strm->time_base, m_in_aud_strm->codec->time_base)) 
        //num_aud_pkt++; 
        av_init_packet(&outpkt); 
        if(pkt.pts != AV_NOPTS_VALUE) 
        { 
         outpkt.pts = aud_pts; 
         PRINT_VAL("ReScaled AUD PTS ", outpkt.pts) 
        } 
        else 
        { 
         outpkt.pts = AV_NOPTS_VALUE; 
        } 

        if(pkt.dts == AV_NOPTS_VALUE) 
        { 
         outpkt.dts = AV_NOPTS_VALUE; 
        } 
        else 
        { 
         outpkt.dts = aud_pts; 
         PRINT_VAL("ReScaled AUD DTS ", outpkt.dts) 
         PRINT_MSG("====================================") 
         if(outpkt.pts >= outpkt.dts) 
         { 
          outpkt.dts = outpkt.pts; 
         } 
         if(outpkt.dts == aud_dts) 
         { 
          outpkt.dts++; 
         } 
         if(outpkt.pts < outpkt.dts) 
         { 
          outpkt.pts = outpkt.dts; 
          aud_pts = outpkt.pts; 
         } 
        } 

        outpkt.data = pkt.data; 
        outpkt.size = pkt.size; 
        outpkt.stream_index = pkt.stream_index; 
        outpkt.flags |= AV_PKT_FLAG_KEY; 
        vid_pts = aud_pts; 
        aud_pts++; 
        if(av_interleaved_write_frame(m_outformat, &outpkt) < 0) 
        { 
         PRINT_MSG("Faile Audio Write ") 
        } 
        else 
        { 
         m_out_aud_strm->codec->frame_number++; 
        } 
        av_free_packet(&outpkt); 
        av_free_packet(&pkt); 
      } 
      else 
      { 
       PRINT_MSG("Got Unknown Pkt ") 
       //num_unkwn_pkt++; 
      } 
      //num_total_pkt++; 
     } 

//8. Finally write trailer and clean up everything 

    av_write_trailer(m_outformat); 
     av_free_packet(&outpkt); 
     av_free_packet(&pkt); 
+0

thanku sehr viel praks411. – Febin

+0

Vielen Dank für das Update. Wie Sie bereits gesagt haben, kann ich die Streams in den Ausgabebehälter kopieren. Aber ich habe einen Fehler [mpegts @ 046bf840] H.264 Bitstream missformed, kein Startcode gefunden, verwenden Sie den Bitstream-Filter h264_ mp4toannexb (-bsf h264_mp4toannexb). Kann ich wissen, wie -bsf h264_mp4toannexb über Code angeben? – Febin

+0

Ich habe BSF bisher nicht benutzt. Aber Sie können es versuchen. Sie können auch ffmpeg.c für weitere Informationen verweisen, da sie es dort verwenden. Auch dir hat meine Antwort geholfen, dann kannst du es richtig markieren :) – praks411

Verwandte Themen