#include <mediademuxer_private.h>
#include <mediademuxer_port.h>
#include <mediademuxer_port_gst.h>
+#include <media_packet_internal.h>
static int gst_demuxer_init(MMHandleType *pHandle);
static int gst_demuxer_prepare(MMHandleType pHandle, char *uri);
{
MEDIADEMUXER_FENTER();
GstPad *apppad = NULL;
+ GstCaps *outcaps = NULL;
+ GstPad *parse_sink_pad = NULL;
+ GstElement *parse_element = NULL;
track *temp = NULL;
+
temp = (track *)(g_malloc(sizeof(track)));
if (!temp) {
MD_E("Not able to allocate memory");
__gst_free_stuct(head);
return MD_ERROR;
}
- MEDIADEMUXER_LINK_PAD(pad, apppad, ERROR);
+ /* Check for type video and it should be h264 */
+ if (strstr(name, "video") && strstr(temp->caps_string, "h264")) {
+ parse_element = gst_element_factory_make("h264parse", NULL);
+ if (!parse_element) {
+ MD_E("factory not able to make h264parse");
+ __gst_free_stuct(head);
+ gst_object_unref(apppad);
+ return MD_ERROR;
+ }
+ gst_bin_add_many(GST_BIN(pipeline),parse_element, NULL);
+ MEDIADEMUXER_SET_STATE(parse_element, GST_STATE_PAUSED, ERROR);
+
+ parse_sink_pad = gst_element_get_static_pad(parse_element, "sink");
+ if (!parse_sink_pad) {
+ MD_E("sink pad of h264parse not available");
+ __gst_free_stuct(head);
+ gst_object_unref(apppad);
+ return MD_ERROR;
+ }
+
+ /* Link demuxer pad with sink pad of parse element*/
+ MEDIADEMUXER_LINK_PAD(pad, parse_sink_pad, ERROR);
+
+ outcaps = gst_caps_new_simple("video/x-h264", "stream-format",G_TYPE_STRING, "byte-stream", NULL);
+ gst_element_link_filtered(parse_element, temp->appsink, outcaps);
+ } else {
+ MEDIADEMUXER_LINK_PAD(pad, apppad, ERROR);
+ }
/*gst_pad_link(pad, fpad) */
if (*head == NULL) {
*head = temp;
int ret = MD_ERROR_NONE;
GstStructure *struc = NULL;
int rate = 0;
+ int bit = 0;
int channels = 0;
int id3_flag = 0;
const gchar *stream_format;
if (mpegversion == 4 || mpegversion == 2 ) {
gst_structure_get_int(struc, "channels", &channels);
gst_structure_get_int(struc, "rate", &rate);
+ gst_structure_get_int(struc, "bit", &bit);
stream_format = gst_structure_get_string(struc, "stream-format");
if (media_format_set_audio_mime(format, MEDIA_FORMAT_AAC_LC))
goto ERROR;
rate = 44100; /* default */
if (media_format_set_audio_samplerate(format, rate))
goto ERROR;
- if (media_format_set_audio_bit(format, 0))
+ if(bit == 0) {
+ bit = 16; /* default */
+ }
+ if (media_format_set_audio_bit(format, bit)) {
goto ERROR;
+ }
if (strncmp(stream_format, "adts", 4) == 0)
media_format_set_audio_aac_type(format, 1);
else
if((layer == 3) || (id3_flag == 1)) {
gst_structure_get_int(struc, "channels", &channels);
gst_structure_get_int(struc, "rate", &rate);
+ gst_structure_get_int(struc, "bit", &bit);
if (media_format_set_audio_mime(format, MEDIA_FORMAT_MP3))
goto ERROR;
if(channels == 0)
rate = 44100; /* default */
if (media_format_set_audio_samplerate(format, rate))
goto ERROR;
- if (media_format_set_audio_bit(format, 0))
+ if (media_format_set_audio_bit(format, bit))
goto ERROR;
}
else {
}
static int _gst_copy_buf_to_media_packet(media_packet_h out_pkt,
- GstBuffer *buffer)
+ GstBuffer *buffer, char *codec_data)
{
MEDIADEMUXER_FENTER();
int ret = MD_ERROR_NONE;
ret = MD_ERROR_UNKNOWN;
goto ERROR;
}
+ if (codec_data) {
+ if (media_packet_set_codec_data(out_pkt, (void*) codec_data, strlen(codec_data))) {
+ MD_E("unable to set the codec data\n");
+ ret = MD_ERROR_UNKNOWN;
+ goto ERROR;
+ }
+ }
ERROR:
gst_buffer_unmap(buffer, &map);
MEDIADEMUXER_FLEAVE();
media_packet_h mediabuf = NULL;
media_format_h mediafmt = NULL;
int indx = 0;
+ char *codec_data = NULL;
+ char *temp_codec_data = NULL;
+ int index = 0;
+
track *atrack = demuxer->info.head;
if ((demuxer->selected_tracks)[track_indx] == false) {
MD_E("Track Not selected\n");
goto ERROR;
}
+ /* Create the codec data and pass to _gst_copy_buf_to_media_packet() to add into the media packet */
+ temp_codec_data = strstr(atrack->caps_string, "codec_data");
+ if (temp_codec_data != NULL) {
+ while (*temp_codec_data != ')') {
+ temp_codec_data++;
+ }
+ temp_codec_data++; /* to esacpe ')' */
+ codec_data = (char*) malloc(sizeof(char)*strlen(temp_codec_data));
+ if (codec_data != NULL) {
+ while (*temp_codec_data != ',') {
+ codec_data[index++] = *temp_codec_data;
+ temp_codec_data++;
+ }
+ codec_data[index] = '\0';
+ }
+ }
+
/* Fill the media_packet with proper information */
- ret = _gst_copy_buf_to_media_packet(mediabuf, buffer);
+ ret = _gst_copy_buf_to_media_packet(mediabuf, buffer, codec_data);
gst_sample_unref(sample);
*outbuf = mediabuf;
+ if (codec_data)
+ free(codec_data);
MEDIADEMUXER_FLEAVE();
return ret;
#include <mediademuxer.h>
#include <media_format.h>
#include <media_packet.h>
+#include <media_codec.h>
/*-----------------------------------------------------------------------
| GLOBAL CONSTANT DEFINITIONS: |
int h;
int channel = 0;
int samplerate = 0;
+int bit = 0;
bool is_adts = 0;
/*-----------------------------------------------------------------------
int write_amrwb_header = 0; /* write magic number for AMR-WB Header at one time */
#endif
+bool validate_with_codec = false;
+mediacodec_h g_media_codec = NULL;
+FILE *fp_out_codec_audio = NULL;
+mediacodec_h g_media_codec_1 = NULL;
+FILE *fp_out_codec_video = NULL;
+
/*-----------------------------------------------------------------------
| HELPER FUNCTION |
-----------------------------------------------------------------------*/
v_mime, w, h);
vid_track = track;
} else if (media_format_get_audio_info(g_media_format[track], &a_mime,
- &channel, &samplerate, NULL, NULL) == MEDIA_FORMAT_ERROR_NONE) {
+ &channel, &samplerate, &bit, NULL) == MEDIA_FORMAT_ERROR_NONE) {
g_print("media_format_get_audio_info is sucess!\n");
- g_print("\t\t[media_format_get_audio]mime:%x, channel :%d, samplerate :%d\n",
- a_mime, channel, samplerate);
+ g_print("\t\t[media_format_get_audio]mime:%x, channel :%d, samplerate :%d, bit :%d\n",
+ a_mime, channel, samplerate, bit);
media_format_get_audio_aac_type(g_media_format[track], &is_adts);
aud_track = track;
} else {
- g_print("Not Supported YET");
+ g_print("Not Supported YET\n");
}
} else {
g_print("Error while getting mediademuxer_get_track_info\n");
return ret;
}
+static void mediacodec_finish(mediacodec_h handle, FILE *fp)
+{
+ int err = 0;
+ fclose(fp);
+ mediacodec_unset_output_buffer_available_cb(handle);
+ err = mediacodec_unprepare(handle);
+ if (err != MEDIACODEC_ERROR_NONE) {
+ g_print("mediacodec_unprepare failed error = %d \n", err);
+ return;
+ }
+ err = mediacodec_destroy(handle);
+ if (err != MEDIACODEC_ERROR_NONE) {
+ g_print("mediacodec_destory failed error = %d \n", err);
+ }
+ return;
+}
+
+static void _mediacodec_fill_audio_buffer_cb(media_packet_h pkt, void *user_data)
+{
+ int err = 0;
+ uint64_t buf_size = 0;
+ void *data = NULL;
+ media_packet_h output_buf;
+
+ if (pkt != NULL) {
+ err = mediacodec_get_output(g_media_codec, &output_buf, 0);
+ if (err == MEDIACODEC_ERROR_NONE) {
+ media_packet_get_buffer_size(output_buf, &buf_size);
+ media_packet_get_buffer_data_ptr(output_buf, &data);
+ if (data != NULL) {
+ fwrite(data, 1, buf_size, fp_out_codec_audio);
+ } else {
+ g_print("Data is null inside _mediacodec_fill_audio_buffer_cb\n");
+ }
+
+ media_packet_destroy(output_buf);
+ } else {
+ g_print("mediacodec_get_output failed inside _mediacodec_fill_audio_buffer_cb err = %d\n", err);
+ return;
+ }
+ } else {
+ g_print("audio pkt from mediacodec is null\n");
+ }
+ return;
+}
+
+static void mediacodec_init_audio(int codecid, int flag, int samplerate, int channel, int bit)
+{
+ /* This file will be used to dump the audio data coming out from mediacodec */
+ fp_out_codec_audio = fopen("/opt/usr/media/codec_dump_audio.out", "wb");
+ if (g_media_codec != NULL) {
+ mediacodec_unprepare(g_media_codec);
+ mediacodec_destroy(g_media_codec);
+ g_media_codec = NULL;
+ }
+ if (mediacodec_create(&g_media_codec) != MEDIACODEC_ERROR_NONE) {
+ g_print("mediacodec_create is failed\n");
+ return;
+ }
+ /* Now set the code info */
+ if ((mediacodec_set_codec(g_media_codec, (mediacodec_codec_type_e)codecid,
+ (mediacodec_support_type_e)flag) != MEDIACODEC_ERROR_NONE)) {
+ g_print("mediacodec_set_codec is failed\n");
+ return;
+ }
+ /* set the audio dec info */
+ if ((mediacodec_set_adec_info(g_media_codec, samplerate, channel, bit))!= MEDIACODEC_ERROR_NONE) {
+ g_print("mediacodec_set_adec is failed\n");
+ return;
+ }
+ /* Set the callback for output data, which will be used to write the data to file */
+ mediacodec_set_output_buffer_available_cb(g_media_codec,
+ _mediacodec_fill_audio_buffer_cb,
+ g_media_codec);
+
+ if (MEDIACODEC_ERROR_NONE != mediacodec_prepare(g_media_codec)) {
+ g_print("mediacodec prepare is failed\n");
+ return;
+ }
+}
+
+static void mediacodec_process_audio_pkt(media_packet_h in_buf)
+{
+ if (g_media_codec != NULL) {
+ /* process the media packet */
+ if (MEDIACODEC_ERROR_NONE != mediacodec_process_input (g_media_codec, in_buf, 0)) {
+ g_print("mediacodec_process_input is failed inside mediacodec_process_audio_pkt\n");
+ return;
+ }
+ }
+}
+
void *_fetch_audio_data(void *ptr)
{
int ret = MD_ERROR_NONE;
*status = -1;
g_print("Audio Data function\n");
+
+ if (validate_with_codec) {
+ int flag = 0;
+ if (a_mime == MEDIA_FORMAT_AAC_LC || a_mime == MEDIA_FORMAT_AAC_HE ||
+ a_mime == MEDIA_FORMAT_AAC_HE_PS) {
+ flag = 10;
+ mediacodec_init_audio(MEDIACODEC_AAC, flag, samplerate, channel, bit);
+ } else {
+ g_print("Not Supported YET- Need to add mime for validating with audio codec\n");
+ return (void *)status;
+ }
+ }
while (1) {
ret = mediademuxer_read_sample(demuxer, aud_track, &audbuf);
if (ret == MD_EOS) {
else
g_print("DUMP : write(audio data) fail for NULL\n");
#endif
- media_packet_destroy(audbuf);
+
+ if (validate_with_codec)
+ mediacodec_process_audio_pkt(audbuf);
+ else
+ media_packet_destroy(audbuf);
}
*status = 0;
+ if (validate_with_codec)
+ mediacodec_finish(g_media_codec, fp_out_codec_audio);
return (void *)status;
}
+static void _mediacodec_fill_video_buffer_cb(media_packet_h pkt, void *user_data)
+{
+ int err = 0;
+ uint64_t buf_size = 0;
+ void *data = NULL;
+ media_packet_h output_buf;
+
+ if (pkt != NULL) {
+ err = mediacodec_get_output(g_media_codec_1, &output_buf, 0);
+ if (err == MEDIACODEC_ERROR_NONE) {
+ media_packet_get_buffer_size(output_buf, &buf_size);
+ //g_print("%s - output_buf size = %lld\n",__func__, buf_size);
+ media_packet_get_buffer_data_ptr(output_buf, &data);
+ if (data != NULL) {
+ fwrite(data, 1, buf_size, fp_out_codec_video);
+ } else {
+ g_print("Data is null inside _mediacodec_fill_video_buffer_cb\n");
+ }
+ media_packet_destroy(output_buf);
+ } else {
+ g_print("mediacodec_get_output failed inside _mediacodec_fill_video_buffer_cb lerr = %d\n", err);
+ return;
+ }
+ } else {
+ g_print("video pkt from mediacodec is null\n");
+ }
+ return;
+}
+
+static void mediacodec_init_video(int codecid, int flag, int width, int height)
+{
+ /* This file will be used to dump the data */
+ fp_out_codec_video = fopen("/opt/usr/media/codec_dump_video.out", "wb");
+ if (g_media_codec_1 != NULL) {
+ mediacodec_unprepare(g_media_codec_1);
+ mediacodec_destroy(g_media_codec_1);
+ g_media_codec_1 = NULL;
+ }
+ if (mediacodec_create(&g_media_codec_1) != MEDIACODEC_ERROR_NONE) {
+ g_print("mediacodec_create is failed\n");
+ return;
+ }
+ /* Now set the code info */
+ if ((mediacodec_set_codec(g_media_codec_1, (mediacodec_codec_type_e)codecid,
+ (mediacodec_support_type_e)flag) != MEDIACODEC_ERROR_NONE)) {
+ g_print("mediacodec_set_codec is failed\n");
+ return;
+ }
+ /* set the video dec info */
+ if ((mediacodec_set_vdec_info(g_media_codec_1, width, height)) != MEDIACODEC_ERROR_NONE) {
+ g_print("mediacodec_set_vdec is failed\n");
+ return;
+ }
+ /* Set the callback for output data, which will be used to write the data to file */
+ mediacodec_set_output_buffer_available_cb(g_media_codec_1,
+ _mediacodec_fill_video_buffer_cb,
+ g_media_codec_1);
+
+ if (MEDIACODEC_ERROR_NONE != mediacodec_prepare(g_media_codec_1)) {
+ g_print("mediacodec_prepare is failed\n");
+ return;
+ }
+}
+
+static void mediacodec_process_video_pkt(media_packet_h in_buf)
+{
+ if (g_media_codec_1 != NULL) {
+ /* process the media packet */
+ if (MEDIACODEC_ERROR_NONE != mediacodec_process_input (g_media_codec_1, in_buf, 0)) {
+ g_print("mediacodec process input is failed inside mediacodec_process_video_pkt\n");
+ return;
+ }
+ } else {
+ g_print("mediacodec handle is invalid inside mediacodec_process_video_pkt()\n");
+ }
+}
+
+#if 0
+static void _local_media_packet_get_codec_data(media_packet_h pkt)
+{
+ unsigned char* get_codec_data;
+ unsigned int get_codec_data_size;
+
+ if (media_packet_get_codec_data(pkt,(void**) &get_codec_data, &get_codec_data_size) == MEDIA_PACKET_ERROR_NONE) {
+ g_print("media_packet_get_codec_data is sucess ... !\n");
+ g_print("codec_data_size = %u\n", get_codec_data_size);
+ get_codec_data[get_codec_data_size] = '\0';
+ if (get_codec_data_size == 0)
+ return;
+ g_print("media packet codec_data is [%s] \n", get_codec_data);
+ } else {
+ g_print("media_packet_get_codec_data is failed...\n");
+ }
+}
+#endif
+
void *_fetch_video_data(void *ptr)
{
int ret = MD_ERROR_NONE;
*status = -1;
g_print("Video Data function\n");
+
+ if (validate_with_codec) {
+ int flag = 0;
+ if (v_mime == MEDIA_FORMAT_H264_SP || v_mime == MEDIA_FORMAT_H264_MP ||
+ v_mime == MEDIA_FORMAT_H264_HP) {
+ flag = 10;
+ mediacodec_init_video(MEDIACODEC_H264, flag, w, h);
+ } else {
+ g_print("Not Supported YET- Need to add mime for validating with video codec\n");
+ return (void *)status;
+ }
+ }
while (1) {
ret = mediademuxer_read_sample(demuxer, vid_track, &vidbuf);
if (ret == MD_EOS) {
media_packet_get_buffer_size(vidbuf, &buf_size);
media_packet_get_buffer_data_ptr(vidbuf, &data);
g_print("Video Read Count::[%4d] frame - get_buffer_size = %"PRIu64"\n", count, buf_size);
-
+#if 0
+ /* This is used for debugging purpose */
+ _local_media_packet_get_codec_data(vidbuf);
+#endif
#if DEMUXER_OUTPUT_DUMP
if (data != NULL)
fwrite(data, 1, buf_size, fp_video_out);
else
g_print("DUMP : write(video data) fail for NULL\n");
#endif
- media_packet_destroy(vidbuf);
+
+ if (validate_with_codec)
+ mediacodec_process_video_pkt(vidbuf);
+ else
+ media_packet_destroy(vidbuf);
}
*status = 0;
+ if (validate_with_codec)
+ mediacodec_finish(g_media_codec_1, fp_out_codec_video);
+
return (void *)status;
}
g_print("d. Destroy \t");
g_print("q. Quit \n");
g_print("---------------------------------------------------------------------------\n");
+ if (validate_with_codec)
+ g_print("[Validation with Media codec]\n");
+ else
+ g_print("[validation as stand alone. To validate with media codec, run mediademuxertest with -c option]\n");
}
void _interpret_main_menu(char *cmd)
g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc) input, NULL);
+ if (argc > 1) {
+ /* Check whether validation with media codec is required */
+ if (argv[1][0] == '-' && argv[1][1] == 'c')
+ validate_with_codec = true;
+ }
displaymenu();
g_print("RUN main loop\n");