Chinaunix首页 | 论坛 | 博客
  • 博客访问: 396970
  • 博文数量: 48
  • 博客积分: 1820
  • 博客等级: 上尉
  • 技术积分: 705
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-28 23:10
文章分类

全部博文(48)

文章存档

2012年(1)

2011年(12)

2010年(34)

2009年(1)

分类: 嵌入式

2010-07-24 00:01:33

#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=<%u>\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=<%d> 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=<%p>,pkt->size=<%d> 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=<%d>,c->pix_fmt=<%d>, len1=<%d>,got_picture=<%d> \n",
    PIX_FMT_YUVJ422P,acc->pix_fmt,len1,got_picture));
   logtrace(("main:avcodec_decode_video PIX_FMT_YUV420P=<%d>\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 ;  
   
}
阅读(1911) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~