2016-08-23 49 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高于第二个(以及随后的数据单调增加)。通过跳过第一个包写入来修复它:)。

相关问题