zoukankan      html  css  js  c++  java
  • ffmpeg处理网络流

    最近遇到好几个人在问ffmpeg如何处理网络流,刚好前段时间也在做这方面,抽空整理了下,把主要代码发出来,希望对大家有用。为简单处理,我这里只简单介绍UDP接收TS流,其实只要是socket接收的都可以类似处理。

    /*
     * main.c
     *
     *  Created on: 2011-9-18
     *      Author: wudegang
     */

    #include "utils.h"
    #include <pthread.h>
    #include <libavcodec/avcodec.h>
    #include <libavformat/avformat.h>

    UdpQueue recvqueue;
    UdpParam udpParam;

    //注册av_read_frame的回调函数,这里只是最简处理,实际应用中应加上出错处理,超时等待...
    int read_data(void *opaque, uint8_t *buf, int buf_size) {
    int size = buf_size;
    int ret;
    // printf("read data %d ", buf_size);
    do {
    ret = get_queue(&recvqueue, buf, buf_size);
    } while (ret);

    // printf("read data Ok %d ", buf_size);
    return size;
    }

    #define BUF_SIZE 4096*500

    int main(int argc, char** argv) {

    init_queue(&recvqueue, 1024*500);

    udpParam.argv = argv;
    udpParam.queue = &recvqueue;
    uint8_t *buf = av_mallocz(sizeof(uint8_t)*BUF_SIZE);


    //UDP接收线程
    pthread_t udp_recv_thread;
    pthread_create(&udp_recv_thread, NULL, udp_ts_recv, &udpParam);
    pthread_detach(udp_recv_thread);



    av_register_all();

    AVCodec *pVideoCodec, *pAudioCodec;
    AVCodecContext *pVideoCodecCtx = NULL;
    AVCodecContext *pAudioCodecCtx = NULL;
    AVIOContext * pb = NULL;
    AVInputFormat *piFmt = NULL;
    AVFormatContext *pFmt = NULL;

    //step1:申请一个AVIOContext
    pb = avio_alloc_context(buf, BUF_SIZE, 0, NULL, read_data, NULL, NULL);
    if (!pb) {
    fprintf(stderr, "avio alloc failed! ");
    return -1;
    }
    //step2:探测流格式
    if (av_probe_input_buffer(pb, &piFmt, "", NULL, 0, 0) < 0) {
    fprintf(stderr, "probe failed! ");
    return -1;
    } else {
    fprintf(stdout, "probe success! ");
    fprintf(stdout, "format: %s[%s] ", piFmt->name, piFmt->long_name);
    }

    pFmt = avformat_alloc_context();
    pFmt->pb = pb; //step3:这一步很关键
    //step4:打开流
    if (avformat_open_input(&pFmt, "", piFmt, NULL) < 0) {
    fprintf(stderr, "avformat open failed. ");
    return -1;
    } else {
    fprintf(stdout, "open stream success! ");
    }
    //以下就和文件处理一致了
    if (av_find_stream_info(pFmt) < 0) {
    fprintf(stderr, "could not fine stream. ");
    return -1;
    }

    av_dump_format(pFmt, 0, "", 0);

    int videoindex = -1;
    int audioindex = -1;
    for (int i = 0; i < pFmt->nb_streams; i++) {
    if ( (pFmt->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
    (videoindex < 0) ) {
    videoindex = i;
    }
    if ( (pFmt->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) &&
    (audioindex < 0) ) {
    audioindex = i;
    }
    }

    if (videoindex < 0 || audioindex < 0) {
    fprintf(stderr, "videoindex=%d, audioindex=%d ", videoindex, audioindex);
    return -1;
    }

    AVStream *pVst,*pAst;
    pVst = pFmt->streams[videoindex];
    pAst = pFmt->streams[audioindex];

    pVideoCodecCtx = pVst->codec;
    pAudioCodecCtx = pAst->codec;

    pVideoCodec = avcodec_find_decoder(pVideoCodecCtx->codec_id);
    if (!pVideoCodec) {
    fprintf(stderr, "could not find video decoder! ");
    return -1;
    }
    if (avcodec_open(pVideoCodecCtx, pVideoCodec) < 0) {
    fprintf(stderr, "could not open video codec! ");
    return -1;
    }

    pAudioCodec = avcodec_find_decoder(pAudioCodecCtx->codec_id);
    if (!pAudioCodec) {
    fprintf(stderr, "could not find audio decoder! ");
    return -1;
    }
    if (avcodec_open(pAudioCodecCtx, pAudioCodec) < 0) {
    fprintf(stderr, "could not open audio codec! ");
    return -1;
    }

    int got_picture;
    uint8_t samples[AVCODEC_MAX_AUDIO_FRAME_SIZE*3/2];
    AVFrame *pframe = avcodec_alloc_frame();
    AVPacket pkt;
    av_init_packet(&pkt);

    while(1) {
    if (av_read_frame(pFmt, &pkt) >= 0) {

    if (pkt.stream_index == videoindex) {
    fprintf(stdout, "pkt.size=%d,pkt.pts=%lld, pkt.data=0x%x.", pkt.size, pkt.pts,(unsigned int)pkt.data);
    avcodec_decode_video2(pVideoCodecCtx, pframe, &got_picture, &pkt);
    if (got_picture) {
    fprintf(stdout, "decode one video frame! ");
    }
    }else if (pkt.stream_index == audioindex) {
    int frame_size = AVCODEC_MAX_AUDIO_FRAME_SIZE*3/2;
    if (avcodec_decode_audio3(pAudioCodecCtx, (int16_t *)samples, &frame_size, &pkt) >= 0) {
    fprintf(stdout, "decode one audio frame! ");
    }
    }
    av_free_packet(&pkt);
    }
    }

    av_free(buf);
    av_free(pframe);
    free_queue(&recvqueue);
    return 0;
    }

    http://bbs.csdn.net/topics/370149110?page=1#post-394494358

  • 相关阅读:
    CentOS查看CPU信息、位数、多核信息
    Linux常用命令大全
    chmod命令详细用法
    tar命令的详细解释
    yum和rpm命令详解
    LeetCode 241. Different Ways to Add Parentheses
    LeetCode 139. Word Break
    LeetCode 201. Bitwise AND of Numbers Range
    LeetCode 486. Predict the Winner
    LeetCode 17. Letter Combinations of a Phone Number
  • 原文地址:https://www.cnblogs.com/yulang314/p/3716043.html
Copyright © 2011-2022 走看看