50,528
社区成员
发帖
与我相关
我的任务
分享
avcodec_init();
avcodec_register_all();
两句话也加了,还是为空,但是codec = avcodec_find_decoder(CODEC_ID_H264);这个可以,不为空。求救//将rgb图像数据填充rgb帧
80.uint8_t * rgb_buff = new uint8_t[nDataLen];
中的nDataLen是什么样的格式不是很明白。int pifu::ks_output_image(const char * e_filename, ks_image_t *src, int bitrate)
{
char suffix[128];
ks_get_suffix(e_filename, suffix);
if (strcmp(suffix, ".jpg") != 0 &&
strcmp(suffix, ".jpeg") != 0 &&
strcmp(suffix, ".png") != 0 &&
strcmp(suffix, ".bmp") != 0 )
return -1;
ks_av_register_all();
AVFormatContext * oc = NULL;
/* allocate the output media context */
avformat_alloc_output_context2(&oc, NULL, NULL, e_filename);
if (!oc)
return -1;
if (strcmp(suffix, ".jpg") == 0 || strcmp(suffix, ".jpeg") == 0 ){
oc->oformat->video_codec = CODEC_ID_MJPEG;
}
else if (strcmp(suffix, ".png") == 0){
oc->oformat->video_codec = CODEC_ID_PNG;
}
else if (strcmp(suffix, ".bmp") == 0){
oc->oformat->video_codec = CODEC_ID_BMP;
}
else{
av_free(oc);
return -1;
}
AVCodecContext *c;
AVStream *st;
st = av_new_stream(oc, 0);
if (!st) {
av_free(oc);
return -1;
}
av_dump_format(oc, 0, e_filename, 1);
c = st->codec;
c->codec_id = oc->oformat->video_codec;
c->codec_type = AVMEDIA_TYPE_VIDEO;
/* put sample parameters */
if (bitrate == 0)
bitrate = src->i_width*src->i_height/5;
c->bit_rate = bitrate; // 无用??
/* resolution must be a multiple of two */
c->width = src->i_width;
c->height = src->i_height;
c->time_base.den = 25;
c->time_base.num = 1;
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
if (c->codec_id == CODEC_ID_MJPEG)
c->pix_fmt = PIX_FMT_YUVJ422P;
else if (c->codec_id == CODEC_ID_PNG)
c->pix_fmt = PIX_FMT_RGB24;
else if (c->codec_id == CODEC_ID_BMP)
c->pix_fmt = PIX_FMT_BGR24;
// some formats want stream headers to be separate
if(oc->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
AVCodec * codec = avcodec_find_encoder(c->codec_id);
if (!codec) {
av_free(oc);
return -1;
}
/* open the codec */
if (avcodec_open(c, codec) < 0) {
av_free(oc);
return -1;
}
//avcodec_encode_video
AVFrame * picture = ks_alloc_picture(c->pix_fmt, c->width, c->height);
if (!picture) {
avcodec_close(c);
av_free(oc);
return -1;
}
if (avio_open(&oc->pb, e_filename, AVIO_FLAG_WRITE) < 0) {
avcodec_close(c);
av_free(oc);
return -1;
}
av_write_header(oc);
int video_outbuf_size = c->width*c->height*3 + 1000000;
uint8_t *video_outbuf = (uint8_t *)av_malloc(video_outbuf_size);
int csp_type;
if (c->codec_id == CODEC_ID_MJPEG)
csp_type = PIFU_CSP_YUVJ422P;
else if (c->codec_id == CODEC_ID_PNG)
csp_type = PIFU_CSP_RGB;
else if (c->codec_id == CODEC_ID_BMP)
csp_type = PIFU_CSP_BGR;
pifu::ks_image_t pic(csp_type, c->width, c->height);
pifu::KsSwscale sws;
sws.scale(src, &pic);
if (csp_type == PIFU_CSP_YUVJ422P)
{
for (int i = 0; i < c->height; i++)
memcpy(picture->data[0] + i*picture->linesize[0], pic.plane[0] + i*pic.i_stride[0], c->width);
for (int i = 0; i < c->height; i++)
{
memcpy(picture->data[1] + i*picture->linesize[1], pic.plane[1] + i*pic.i_stride[1], c->width/2);
memcpy(picture->data[2] + i*picture->linesize[2], pic.plane[2] + i*pic.i_stride[2], c->width/2);
}
}
else
{
for (int i = 0; i < c->height; i++)
memcpy(picture->data[0] + i*picture->linesize[0], pic.plane[0] + i*pic.i_stride[0], c->width*3);
}
int out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture);
/* if zero size, it means the image was buffered */
if (out_size > 0) {
AVPacket pkt;
av_init_packet(&pkt);
pkt.pts = 0;
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.stream_index= 0;
pkt.data= video_outbuf;
pkt.size= out_size;
av_interleaved_write_frame(oc, &pkt);
}
av_write_trailer(oc);
avcodec_close(c);
av_free(picture->data[0]);
av_free(picture);
//avformat_free_context(oc);
av_freep(&oc->streams[0]);
avio_close(oc->pb);
av_free(oc);
av_free(video_outbuf);
return 0;
}