2016-08-23 60 views
-2

我試圖使用dranger tutorials將RTSP h264流式傳輸的視頻直接寫入文件而不進行解碼和編碼(ffmpeg 3.0/3.1庫)。但是我有點遺憾,我得到相應的AVPacket後,如何爲av_write_frame填充AVFormatContext指針。Remux RTSP流入容器? (在沒有解碼的情況下寫入讀取幀)

試圖澄清。我想要做的就是這個

1. Open webcam stream in h264 
2. Read a frame 
3. Save it to a file without decoding and encoding it. 

編輯:我還試圖用FFmpeg的文檔中的remuxing例子(做一個網絡的init()),但是從去當我得到DTS和PTS同步錯誤RTSP - > .MP4

複製粘貼從教程中的代碼:

#include <stdio.h> 
#include <libavutil/pixfmt.h> 
#include <libavcodec/avcodec.h> 
#include <libavutil/avconfig.h> 
#include <libswscale/swscale.h> 
#include <libavformat/avformat.h> 

int main(int argc, char *argv[]) { 
    av_register_all(); 
    avcodec_register_all(); 
    avformat_network_init(); 

    AVFormatContext *pFormatCtx = avformat_alloc_context(); 

    // Camera comes from argv[1] 
    avformat_open_input(&pFormatCtx, argv[1], NULL, NULL); 
    avformat_find_stream_info(pFormatCtx, NULL); 
    av_dump_format(pFormatCtx, 0, argv[1], 0); 

    int video_stream_idx = -1; 

    for (int i = 0; i < pFormatCtx->nb_streams; i++) { 
     if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { 
      video_stream_idx = i; 
      break; 
     } 
    } 

    AVCodecContext *pCodecContext = NULL; 
    AVCodecContext *pCodecContextOrig = NULL; 

    pCodecContextOrig = pFormatCtx->streams[video_stream_idx]->codec; 
    AVCodec *pCodec; 
    pCodec = avcodec_find_decoder(pCodecContextOrig->codec_id); 
    pCodecContext = avcodec_alloc_context3(pCodec); 
    avcodec_copy_context(pCodecContext, pCodecContextOrig); 
    avcodec_open2(pCodecContext, pCodec, NULL); 

    AVFrame *pFrame = av_frame_alloc(); 
    AVFrame *pFrameRGB = av_frame_alloc(); 

    uint8_t *buffer = NULL; 
    int buffer_size = avpicture_get_size(AV_PIX_FMT_RGB24, pCodecContext->width, 
             pCodecContext->height); 
    buffer = (uint8_t *)av_malloc(buffer_size * sizeof(uint8_t)); 

    // fill buffer 
    avpicture_fill((AVPicture *)pFrameRGB, buffer, AV_PIX_FMT_RGB24, 
        pCodecContext->width, pCodecContext->height); 

    struct SwsContext *sws_ctx = NULL; 
    int frame_finished = 0; 
    AVPacket packet; 

    // Size(src), fmt(src), Size(dst), fmt(dst) .. flags 
    sws_ctx = sws_getContext(pCodecContext->width, pCodecContext->height, 
          pCodecContext->pix_fmt, pCodecContext->width, 
          pCodecContext->height, AV_PIX_FMT_RGB24, 
          SWS_BILINEAR, NULL, NULL, NULL); 


    AVFormatContext *out_fmt_ctx; 

    avformat_write_header(out_fmt_ctx, NULL); 

    int i = 0; 
    while (i < 100 && (av_read_frame(pFormatCtx, &packet) >= 0)) { 
     // Want to write these frames to disk 
     i++; 
    } 

    av_write_trailer(out_fmt_ctx); 

    av_free(buffer); 
    av_free(pFrameRGB); 
    av_free(pFrame); 

    avcodec_close(pCodecContext); 
    avcodec_close(pCodecContextOrig); 

    avformat_close_input(&pFormatCtx); 

    return 0; 
} 

我想了很多的這個代碼的東西可以被刪除。我正在嘗試學習 :)。

鏈接針對-lavutil -lavformat -lavcodec -lz -lavutil -lm -lswscale

+1

你有沒有考慮過發佈[MCVE](http://stackoverflow.com/help/mcve)? – Mirakurun

+1

這取決於編解碼器和容器類型。 – szatmary

+0

@szatmary我已經更新了一些問題。 – Aram

回答

0

我固定通過使用從FFmpeg的文檔remuxing.c例子。問題是由於某種原因(我仍然不知道爲什麼)第一個數據包的dts和pts高於第二個(以及隨後的數據單調增加)。通過跳過第一個包寫入來修復它:)。

相關問題