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

    http://blog.sina.com.cn/s/blog_675142dc01010otk.html

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

    #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;
    }

  • 相关阅读:
    poj3278 Catch That Cow
    poj2251 Dungeon Master
    poj1321 棋盘问题
    poj3083 Children of the Candy Cor
    jvm基础知识—垃圾回收机制
    jvm基础知识1
    java面试基础必备
    java soket通信总结 bio nio aio的区别和总结
    java scoket aIO 通信
    java scoket Blocking 阻塞IO socket通信四
  • 原文地址:https://www.cnblogs.com/jingzhishen/p/3668088.html
Copyright © 2011-2022 走看看