采集视频 linux c,基于嵌入式Linux的视频采集系统-----源程序----decoder.cpp

#include "decoder.h"

#include

#include "log.h"

static int sws_flags = SWS_BICUBIC;

CDecoder::CDecoder():cur_process_pos(0),cur_append_pos(0),num_has_append(0)

{

logtrace(("CDecoder::CDecoder==>> begin ...\n"));

m_frame_que.resize(10);

logtrace(("m_frame_que.size=\n",m_frame_que.size()));

/* must be called before using avcodec lib */

avcodec_init();

avcodec_register_all();

av_register_all();

int err = pthread_mutex_init(&m_mutex,NULL);

if(err)

{

logerror(("CDecoder::CDecoder pthread mutex init fail\n"));

return;

}

err = pthread_cond_init(&m_pthread_cond,NULL);

if(err)

{

logerror(("CDecoder::CDecoder pthread cond init fail\n"));

return;

}

logtrace(("CDecoder::CDecoder==>> end ok\n"));

}

CDecoder::~CDecoder()

{

}

AVFrame * CDecoder::do_alloc_picture(int pix_fmt, int width, int height)

{

AVFrame *picture;

uint8_t *picture_buf;

int size;

picture = avcodec_alloc_frame();

if (!picture)

return NULL;

size = avpicture_get_size(pix_fmt, width, height);

logtrace(("do_alloc_picture:%d \n",size));

picture_buf = (uint8_t*)malloc(size);

if (!picture_buf) {

av_free(picture);

return NULL;

}

avpicture_fill((AVPicture *)picture, picture_buf,

pix_fmt, width, height);

return picture;

}

void CDecoder::push_frame(void* img,int size)

{

pthread_mutex_lock(&m_mutex);

TFrameNode& var_frame = m_frame_que[cur_append_pos];

if(size>DEF_FRAME_SIZE) return;

var_frame.size = size;

memcpy(var_frame.buff,img,size);

var_frame.pkt.data = (uint8_t*)var_frame.buff;

var_frame.pkt.size = size;

cur_append_pos++;

cur_append_pos = cur_append_pos%m_frame_que.size();

if(cur_append_pos == cur_process_pos)

{

num_has_append = cur_append_pos;

cur_process_pos = 0;

}

else

num_has_append ++;

pthread_cond_signal(&m_pthread_cond);

pthread_mutex_unlock(&m_mutex);

}

AVPacket* CDecoder::pop_frame()

{

AVPacket* ptrFrame=NULL;

if(0 == num_has_append) return ptrFrame;

ptrFrame = &(m_frame_que[cur_process_pos]).pkt;

cur_process_pos ++;

cur_process_pos = cur_process_pos % m_frame_que.size();

num_has_append--;

return ptrFrame;

}

char* CDecoder::readall_file(const string& file,int & size)

{

FILE* fptr;

size = 0;

int readnum;

fptr = fopen(file.c_str(),"r");

char* base_buff =(char*) malloc(10844+100);

char* mybuff = base_buff;

do{

readnum = fread(mybuff,1,1,fptr);

mybuff += readnum;

size += readnum;

}while(readnum);

printf("readall_file size= ok\n",size);

return base_buff;

}

void CDecoder::try_show(AVFrame* dest_frame,int width,int height)

{

int  got_picture,len1;

int dst_pix_fmt;

struct SwsContext *img_convert_ctx = NULL;

AVCodecContext *acc =NULL;

AVFrame *frame = NULL;

AVCodec *codec =NULL;

AVPacket  *pkt = NULL;//! no need to free

logtrace(("try_show begin...\n"));

pthread_mutex_lock(&m_mutex);

do{

pkt = pop_frame();

if(pkt != NULL){

memcpy(m_convert_buff.buff,pkt->data,pkt->size);

pkt->data =(uint8_t*) m_convert_buff.buff;

}

else{

pthread_cond_wait(&m_pthread_cond, &m_mutex);

pkt = pop_frame();

}

}while( pkt == NULL);

pthread_mutex_unlock (&m_mutex);

if(pkt == NULL)

{

logtrace(("try_show pop_frame none new frame...\n"));

goto clean;

}

logtrace(("main:main pkt->data=,pkt->size= ok\n",pkt->data,pkt->size));

frame= avcodec_alloc_frame();

acc= avcodec_alloc_context();

codec = avcodec_find_decoder(CODEC_ID_MJPEG);

if (!codec) {

fprintf(stderr, "codec not found\n");

goto clean;

}

if (avcodec_open(acc, codec) < 0) {

fprintf(stderr, "could not open codec\n");

goto clean;

}

len1 = avcodec_decode_video(acc,

frame, &got_picture,

pkt->data, pkt->size);

logtrace(("main:avcodec_decode_video PIX_FMT_YUVJ422P=,c->pix_fmt=, len1=,got_picture= \n",

PIX_FMT_YUVJ422P,acc->pix_fmt,len1,got_picture));

logtrace(("main:avcodec_decode_video PIX_FMT_YUV420P=\n",PIX_FMT_YUV420P));

if(len1<0)

goto clean;

if(got_picture<=0)

goto clean;

dst_pix_fmt = (int)PIX_FMT_YUV420P ;//PIX_FMT_YUV420P;

img_convert_ctx = sws_getCachedContext(img_convert_ctx,

acc->width, acc->height,

acc->pix_fmt,

width, height,

(PixelFormat)dst_pix_fmt, sws_flags, NULL, NULL, NULL);

if (img_convert_ctx == NULL) {

fprintf(stderr, "Cannot initialize the conversion context\n");

goto clean;

}

sws_scale(img_convert_ctx, frame->data, frame->linesize,

0, acc->height, dest_frame->data, dest_frame->linesize);

logtrace(("try_show end ok...\n"));

clean:

//fprintf(stderr, "CDecoder::try_show==>RROR ocured ....\n");

if(img_convert_ctx != NULL)

sws_freeContext(img_convert_ctx);

if(acc != NULL)

{

avcodec_close(acc);

av_free(acc);

}

if(frame != NULL)

av_free(frame);

//if(codec !=NULL)

//av_free(codec);

return ;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值