Commit 9f73be62 authored by DanmeiChen's avatar DanmeiChen

extract the video size

parent 3555dbbd
......@@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "mediastreamer2/msvideo.h"
#include "mediastreamer2/msticker.h"
#include "android_mediacodec.h"
#include "h264utils.h"
#include <jni.h>
#include <media/NdkMediaCodec.h>
......@@ -54,7 +55,7 @@ typedef struct _DecData {
static int dec_init_mediacodec(DecData *d) {
AMediaFormat *format;
media_status_t status = 0;
MSVideoSize initial_size={0};
if (d->codec == NULL){
d->codec = AMediaCodec_createDecoderByType("video/avc");
if (d->codec == NULL){
......@@ -62,12 +63,15 @@ static int dec_init_mediacodec(DecData *d) {
return AMEDIA_ERROR_UNKNOWN;
}
}
format = AMediaFormat_new();
AMediaFormat_setString(format, "mime", "video/avc");
//Size mandatory for decoder configuration
AMediaFormat_setInt32(format, "width", 1920);
AMediaFormat_setInt32(format, "height", 1080);
if(d->sps) {
update_picture_size_with_sps(d->sps, &initial_size);
AMediaFormat_setInt32(format, "width", initial_size.width);
AMediaFormat_setInt32(format, "height", initial_size.height);
}
if ((d->useMediaImage = AMediaImage_isAvailable())) AMediaFormat_setInt32(format, "color-format", 0x7f420888);
......@@ -110,13 +114,6 @@ static void dec_init(MSFilter *f) {
static void dec_preprocess(MSFilter *f) {
DecData *d = (DecData *)f->data;
d->first_image_decoded = FALSE;
/*we shall allocate the MediaCodec decoder the last as possible and after the encoder, because
* on some phones hardware encoder and decoders can't be allocated at the same time.
* So let's give preference to the encoder.
**/
if (d->codec == NULL) dec_init_mediacodec(d);
}
static void dec_postprocess(MSFilter *f) {
......@@ -285,11 +282,6 @@ static void dec_process(MSFilter *f) {
AMediaCodecBufferInfo info;
unsigned int unpacking_ret;
if (d->codec == NULL){
ms_queue_flush(f->inputs[0]);
return;
}
if (d->packet_num == 0 && d->sps && d->pps) {
rfc3984_unpack_out_of_band_sps_pps(&d->unpacker, d->sps, d->pps);
d->sps = NULL;
......@@ -302,7 +294,6 @@ static void dec_process(MSFilter *f) {
int size;
uint8_t *buf = NULL;
ssize_t iBufidx;
unpacking_ret = rfc3984_unpack2(&d->unpacker, im, &nalus);
if (!(unpacking_ret & Rfc3984FrameAvailable)) continue;
......@@ -326,6 +317,12 @@ static void dec_process(MSFilter *f) {
if (unpacking_ret & Rfc3984IsKeyFrame) ms_message("MSMediaCodecH264Dec: I-frame received");
size = nalusToFrame(d, &nalus, &need_reinit);
//Initialise the video size
if((d->codec==NULL) && d->sps) {
dec_init_mediacodec(d);
}
if (d->codec == NULL) continue;
if (need_reinit) {
//In case of remote rotation, the decoder needs to flushed in order to restart with the new video size
......@@ -398,7 +395,7 @@ static void dec_process(MSFilter *f) {
if (d->useMediaImage) {
AMediaImage image;
if (AMediaCodec_getOutputImage(d->codec, oBufidx, &image)) {
int dst_pix_strides[4] = {1, 1, 1, 1};
MSRect dst_roi = {0, 0, image.crop_rect.w, image.crop_rect.h};
......@@ -415,7 +412,7 @@ static void dec_process(MSFilter *f) {
}
} else {
int width = 0, height = 0;
format = AMediaCodec_getOutputFormat(d->codec);
if (format != NULL) {
......@@ -444,6 +441,7 @@ static void dec_process(MSFilter *f) {
ms_error("MSMediaCodecH264Dec: width and height are not known !");
}
}
if (om){
if (!d->first_image_decoded) {
......
......@@ -19,20 +19,23 @@
#include "h264utils.h"
#include <mediastreamer2/msqueue.h>
#include "mediastreamer2/bits_rw.h"
#include <math.h>
typedef struct _MSBitsReader {
const uint8_t *data;
uint8_t mask;
int index;
} MSBitsReader;
} MSBitsReaderPrivate;
static void ms_bits_reader_init(MSBitsReader *br, const uint8_t *data) {
static void ms_bits_reader_init_private(MSBitsReaderPrivate *br, const uint8_t *data) {
br->data = data;
br->mask = 0x80;
br->index = 0;
}
static unsigned int ms_bits_reader_read_as_uint(MSBitsReader *br, int n) {
static unsigned int ms_bits_reader_read_as_uint(MSBitsReaderPrivate *br, int n) {
unsigned int value = 0;
int i;
for(i=0; i<n; i++) {
......@@ -54,9 +57,9 @@ static unsigned int ms_bits_reader_read_as_uint(MSBitsReader *br, int n) {
static unsigned int ms_h264_exp_golomb_code_to_uint(const uint8_t *data) {
int leading_zero_bits = -1;
bool_t b = FALSE;
MSBitsReader bits_reader;
MSBitsReaderPrivate bits_reader;
ms_bits_reader_init(&bits_reader, data);
ms_bits_reader_init_private(&bits_reader, data);
while (!b) {
b = ms_bits_reader_read_as_uint(&bits_reader, 1);
leading_zero_bits++;
......@@ -153,3 +156,93 @@ void ms_h264_stream_to_nalus(const uint8_t *frame, size_t size, MSQueue *nalus,
ms_queue_put(nalus, nalu);
}
}
void update_picture_size_with_sps(const mblk_t* sps, MSVideoSize *video_size) {
MSBitsReader reader;
/* init reader, but skip 1 byte (nal_unit_type) */
ms_bits_reader_init(&reader, sps->b_rptr + 1, sps->b_wptr - sps->b_rptr - 1);
unsigned int profile_idc;
ms_bits_reader_n_bits(&reader, 8, &profile_idc, "profile_idc");
ms_bits_reader_n_bits(&reader, 1, NULL, "constraint_set0_flag");
ms_bits_reader_n_bits(&reader, 1, NULL, "constraint_set1_flag");
ms_bits_reader_n_bits(&reader, 1, NULL, "constraint_set2_flag");
ms_bits_reader_n_bits(&reader, 5, NULL, "reserved_zero_5bits");
ms_bits_reader_n_bits(&reader, 8, NULL, "level_idc");
ms_bits_reader_ue(&reader, NULL, "seq_parameter_set_id");
if (profile_idc == 100) {
{
ms_bits_reader_ue(&reader, NULL, "chroma_format_idc");
}
ms_bits_reader_ue(&reader, NULL, "bit_depth_luma_minus8");
ms_bits_reader_ue(&reader, NULL, "bit_depth_chroma_minus8");
ms_bits_reader_n_bits(&reader, 1, NULL, "qpprime_y_zero_transform_bypass_flag");
ms_bits_reader_n_bits(&reader, 1, NULL, "seq_scaling_matrix_present_flag");
}
ms_bits_reader_ue(&reader, NULL, "log2_max_frame_num_minus4");
unsigned int pic_order_cnt_type;
ms_bits_reader_ue(&reader, &pic_order_cnt_type, "pic_order_cnt_type");
if (pic_order_cnt_type == 0) {
ms_bits_reader_ue(&reader, NULL, "log2_max_pic_order_cnt_lsb_minus4");
} else if (pic_order_cnt_type == 1) {
int i;
{
ms_bits_reader_n_bits(&reader, 1, NULL, "delta_pic_order_always_zero_flag");
}
ms_bits_reader_se(&reader, NULL, "offset_for_non_ref_pic");
ms_bits_reader_se(&reader, NULL, "offset_for_top_to_bottom_field");
{
unsigned int num_ref_frames_in_pic_order_cnt_cycle;
ms_bits_reader_ue(&reader, &num_ref_frames_in_pic_order_cnt_cycle, "num_ref_frames_in_pic_order_cnt_cycle");
for (i = 0; i<(int)num_ref_frames_in_pic_order_cnt_cycle; i++) {
ms_bits_reader_se(&reader, NULL, "offset_for_ref_frame[ i ]");
}
}
}
ms_bits_reader_ue(&reader, NULL, "num_ref_frames");
ms_bits_reader_n_bits(&reader, 1, NULL, "gaps_in_frame_num_value_allowed_flag");
unsigned int pic_width_in_mbs_minus1;
ms_bits_reader_ue(&reader, &pic_width_in_mbs_minus1, "pic_width_in_mbs_minus1");
unsigned int pic_height_in_map_units_minus1;
ms_bits_reader_ue(&reader, &pic_height_in_map_units_minus1, "pic_height_in_map_units_minus1");
unsigned int frame_mbs_only_flag;
ms_bits_reader_n_bits(&reader, 1, &frame_mbs_only_flag, "frame_mbs_only_flag");
if (!frame_mbs_only_flag) {
ms_bits_reader_n_bits(&reader, 1, NULL, "mb_adaptive_frame_field_flag");
}
ms_bits_reader_n_bits(&reader, 1, NULL, "direct_8x8_inference_flag");
unsigned int frame_cropping_flag;
ms_bits_reader_n_bits(&reader, 1, &frame_cropping_flag, "frame_cropping_flag");
if (frame_cropping_flag) {
unsigned int frame_crop_left_offset;
ms_bits_reader_ue(&reader, &frame_crop_left_offset, "frame_crop_left_offset");
unsigned int frame_crop_right_offset;
ms_bits_reader_ue(&reader, &frame_crop_right_offset, "frame_crop_right_offset");
video_size->width = ((pic_width_in_mbs_minus1+1)*16)-frame_crop_left_offset*2-frame_crop_right_offset*2;
unsigned int frame_crop_top_offset;
ms_bits_reader_ue(&reader, &frame_crop_top_offset, "frame_crop_top_offset");
unsigned int frame_crop_bottom_offset;
ms_bits_reader_ue(&reader, &frame_crop_bottom_offset, "frame_crop_bottom_offset");
video_size->height = ((2-frame_mbs_only_flag)*(pic_height_in_map_units_minus1+1)*16)-(frame_crop_top_offset*2)-(frame_crop_bottom_offset*2);
}
else {
video_size->width = (pic_width_in_mbs_minus1+1)*16;
video_size->height = (2-frame_mbs_only_flag)*(pic_height_in_map_units_minus1+1)*16;
}
ms_bits_reader_n_bits(&reader, 1, NULL, "vui_parameters_present_flag");
}
......@@ -21,6 +21,7 @@
#define H264_UTILS_H
#include <mediastreamer2/msqueue.h>
#include "mediastreamer2/msvideo.h"
/**
* Enumeration that lists the different type of NAL unit
......@@ -74,4 +75,9 @@ void ms_h264_bitstream_to_nalus(const uint8_t *bitstream, size_t size, MSQueue *
*/
void ms_h264_stream_to_nalus(const uint8_t *frame, size_t size, MSQueue *nalus, int *idr_count);
/**
* Set the video size from sps
* @param sps The sps unit to read
*/
void update_picture_size_with_sps(const mblk_t* sps, MSVideoSize *video_size);
#endif /* defined(H264_UTILS_H) */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment