こんにちは、 と を使用android
しffmpeg
て Wowza サーバーにストリーミングしています。そのandroid
部分では、私はこれだけを持っています:
public synchronized void onPreviewFrame(byte[] data, Camera camera) {
/* get video data */
naStream(data); // native method
}
ネイティブ側ffmpeg
では (frame_video は からのバイト配列ですandroid
):
av_init_packet(&pkt);
avpicture_fill((AVPicture *)picture,frame_video,PIX_FMT_YUV420P,640,480);
if(ret == 0)
LOGI(7,"avpicture_fill -> error %d", ret);
/* encode the image */
pkt.data = NULL;
pkt.size = 0;
ret = avcodec_encode_video2(video_c, &pkt, picture, &got_packet);
if(ret != 0)
LOGI(7,"avcodec_encode_video2 -> error %d", ret);
/* if zero size, it means the image was buffered */
if (got_packet) {
if (pkt.pts != AV_NOPTS_VALUE) {
pkt.pts = av_rescale_q(picture->pts, video_c->time_base, AV_TIME_BASE_Q);
}
if (pkt.dts != AV_NOPTS_VALUE) {
pkt.dts = av_rescale_q(pkt.dts, video_c->time_base, AV_TIME_BASE_Q);
}
pkt.duration = av_rescale_q(video_st->duration, video_c->time_base, video_st->time_base);
if (video_c->coded_frame->key_frame)
pkt.flags |= AV_PKT_FLAG_KEY;
/* write the compressed frame in the media file */
ret = av_interleaved_write_frame(oc, &pkt);
ここでの問題は、ストリームがグレースケールで到着することです... 次を使用してNV21からYUV420Pに変換しようとしました:
img_convert_ctx = sws_getContext(video_c->width, video_c->height,PIX_FMT_NV21, video_c->width, video_c->height,PIX_FMT_YUV420P,SWS_FAST_BILINEAR | SWS_PRINT_INFO, NULL, NULL, NULL);
sws_scale(img_convert_ctx, (const uint8_t * const*)picture->data, picture->linesize, 0,video_c->height, tmp_picture->data, tmp_picture->linesize);
sws_freeContext(img_convert_ctx);
しかし、その後、write_interleaved パケットを作成できません...
「picture」と「tmp_picture」の割り当てを次のように行っています。
picture = avcodec_alloc_frame();
tmp_picture = avcodec_alloc_frame();
numBytes=avpicture_get_size(PIX_FMT_YUV420P, video_c->width, video_c->height);
buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
avpicture_fill((AVPicture *)tmp_picture, buffer, PIX_FMT_YUV420P,video_c->width, video_c->height);
次の行を削除した後:
if (pkt.pts != AV_NOPTS_VALUE) {
pkt.pts = av_rescale_q(picture->pts, video_c->time_base, AV_TIME_BASE_Q);
}
if (pkt.dts != AV_NOPTS_VALUE) {
pkt.dts = av_rescale_q(pkt.dts, video_c->time_base, AV_TIME_BASE_Q);
}
そして追加しました:
if (video_c->coded_frame->pts != AV_NOPTS_VALUE)
pkt.pts = av_rescale_q(video_c->coded_frame->pts,video_c->time_base, video_st->time_base);
インターリーブされたパケットの書き込みを開始しましたが、wowza では何も表示されません... 誰か助けてくれませんか?