[ACR-877] Add new APIs for muxed stream data callback 04/113104/5
authorJeongmo Yang <jm80.yang@samsung.com>
Mon, 6 Feb 2017 05:54:03 +0000 (14:54 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Fri, 10 Feb 2017 02:00:23 +0000 (11:00 +0900)
The new APIs will provide muxed stream callback.
User can get the data pointer while recording and it is same with recorded file.

[Version] 0.2.50
[Profile] Common
[Issue Type] Update
[Dependency module] N/A
[Test] [M(T) - Boot=(OK), sdb=(OK), Home=(OK), Touch=(OK), Version=tizen-3.0-mobile_20170203.1]

Change-Id: Ie6d99950a9b75f0a06090a47b4ad6307c61d0904
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
include/recorder.h
packaging/capi-media-recorder.spec
src/recorder.c
test/recorder_test.c

index fb9be7e89af0549bc13c402d8300fb87f966c930..86ebf95988fd449474e6eb216c24d0bbe2cde367 100644 (file)
@@ -193,7 +193,7 @@ typedef enum {
  * @details The callback function is possible to receive three types of limits: time, size and no-space.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @remarks After being called, recording data is discarded and not written in the recording file. Also the state of recorder is not changed.
- * @param[in] type The imitation type
+ * @param[in] type      The imitation type
  * @param[in] user_data The user data passed from the callback registration function
  * @pre You have to register a callback using recorder_set_recording_limit_reached_cb().
  * @see recorder_set_recording_status_cb()
@@ -219,10 +219,10 @@ typedef void (*recorder_recording_status_cb)(unsigned long long elapsed_time, un
 /**
  * @brief Called when the record state is changed.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in] previous The previous state of the recorder
- * @param[in] current  The current state of the recorder
- * @param[in] by_policy     @c true if the state is changed by policy, otherwise @c false if the state is not changed
- * @param[in] user_data        The user data passed from the callback registration function
+ * @param[in] previous  The previous state of the recorder
+ * @param[in] current   The current state of the recorder
+ * @param[in] by_policy @c true if the state is changed by policy, otherwise @c false if the state is not changed
+ * @param[in] user_data The user data passed from the callback registration function
  * @pre This function is required to register a callback using recorder_set_state_changed_cb().
  * @see        recorder_set_state_changed_cb()
  * @see        recorder_prepare()
@@ -237,8 +237,8 @@ typedef void (*recorder_state_changed_cb)(recorder_state_e previous , recorder_s
 /**
  * @brief Called when the recorder device state is changed.
  * @since_tizen 3.0
- * @param[in] type The recorder type
- * @param[in] state The state of the recorder device
+ * @param[in] type      The recorder type
+ * @param[in] state     The state of the recorder device
  * @param[in] user_data The user data passed from the callback registration function
  * @see        recorder_add_device_state_changed_cb()
  */
@@ -261,15 +261,29 @@ typedef void (*recorder_interrupted_cb)(recorder_policy_e policy, recorder_state
  * @remarks The callback function holds the same buffer that will be recorded. \n
  *          So if the user changes the buffer, the result file will contain the buffer.
  * @remarks The callback is called via internal thread of Frameworks, therefore do not invoke UI API, recorder_unprepare(), recorder_commit() and recorder_cancel() in callback.
- * @param[in] stream The audio stream data
- * @param[in] size The size of the stream data
- * @param[in] format The audio format
- * @param[in] channel The number of the channel
+ * @param[in] stream    The audio stream data
+ * @param[in] size      The size of the stream data
+ * @param[in] format    The audio format
+ * @param[in] channel   The number of the channel
  * @param[in] timestamp The timestamp of the stream buffer (in msec)
  * @param[in] user_data The user data passed from the callback registration function
  * @see recorder_set_audio_stream_cb()
  */
-typedef void (*recorder_audio_stream_cb)(void* stream, int size, audio_sample_type_e format, int channel, unsigned int timestamp, void *user_data);
+typedef void (*recorder_audio_stream_cb)(void *stream, int size, audio_sample_type_e format, int channel, unsigned int timestamp, void *user_data);
+
+/**
+ * @brief Called when muxed stream data is delivered just before writing to the file.
+ * @since_tizen 4.0
+ * @remarks This callback receives the data that will be recorded, \n
+ *          but any changes to this data will not affect the recorded file. \n
+ *          The @a stream should not be freed and it's valid only in the callback. To use outside the callback, make a copy.
+ * @param[in] stream    The muxed stream data
+ * @param[in] size      The size of the stream data
+ * @param[in] offset    The offset of the stream data
+ * @param[in] user_data The user data passed from the callback registration function
+ * @see recorder_set_muxed_stream_cb()
+ */
+typedef void (*recorder_muxed_stream_cb)(void *stream, int size, unsigned long long offset, void *user_data);
 
 /**
  * @brief Called once for each supported video resolution.
@@ -313,8 +327,8 @@ typedef void (*recorder_error_cb)(recorder_error_e error, recorder_state_e curre
 /**
  * @brief Called iteratively to notify about the supported file formats.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in] format   The format of recording files
- * @param[in] user_data        The user data passed from the foreach function
+ * @param[in] format    The format of recording files
+ * @param[in] user_data The user data passed from the foreach function
  * @return @c true to continue with the next iteration of the loop, \n otherwise @c false to break out of the loop
  * @pre recorder_foreach_supported_file_format() will invoke this callback.
  * @see        recorder_foreach_supported_file_format()
@@ -324,8 +338,8 @@ typedef bool (*recorder_supported_file_format_cb)(recorder_file_format_e format,
 /**
  * @brief Called iteratively to notify about the supported audio encoders.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in] codec    The codec of audio encoder
- * @param[in] user_data        The user data passed from the foreach function
+ * @param[in] codec     The codec of audio encoder
+ * @param[in] user_data The user data passed from the foreach function
  * @return @c true to continue with the next iteration of the loop, \n otherwise @c false to break out of the loop
  * @pre recorder_foreach_supported_audio_encoder() will invoke this callback.
  * @see        recorder_foreach_supported_audio_encoder()
@@ -335,8 +349,8 @@ typedef bool (*recorder_supported_audio_encoder_cb)(recorder_audio_codec_e codec
 /**
  * @brief Called iteratively to notify about the supported video encoders.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in] codec    The codec of video encoder
- * @param[in] user_data        The user data passed from the foreach function
+ * @param[in] codec     The codec of video encoder
+ * @param[in] user_data The user data passed from the foreach function
  * @return @c true to continue with the next iteration of the loop, \n otherwise @c false to break out of the loop
  * @pre recorder_foreach_supported_video_encoder() will invoke this callback.
  * @see        recorder_foreach_supported_video_encoder()
@@ -364,8 +378,8 @@ typedef bool (*recorder_supported_video_encoder_cb)(recorder_video_codec_e codec
  * #CAMERA_STATE_CREATED -> #RECORDER_STATE_CREATED\n
  * #CAMERA_STATE_PREVIEW -> #RECORDER_STATE_READY\n
  * #CAMERA_STATE_CAPTURED -> #RECORDER_STATE_READY
- * @param[in]   camera The handle to the camera
- * @param[out]  recorder       A handle to the recorder
+ * @param[in]  camera       The handle to the camera
+ * @param[out] recorder     A handle to the recorder
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -591,7 +605,7 @@ int recorder_cancel(recorder_h recorder);
  * @brief Gets the recorder's current state.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @param[in]  recorder The handle to the media recorder
- * @param[out] state  The current state of the recorder
+ * @param[out] state    The current state of the recorder
  * @return  @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -606,7 +620,7 @@ int recorder_get_state(recorder_h recorder, recorder_state_e *state);
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @remarks @c 0 dB indicates maximum input level, @c -300 dB indicates minimum input level.
  * @param[in]  recorder The handle to the media recorder
- * @param[out] dB  The audio input level in dB
+ * @param[out] dB       The audio input level in dB
  * @return  @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -623,8 +637,8 @@ int recorder_get_audio_level(recorder_h recorder, double *dB);
  * @details This function sets file path which defines where newly recorded data should be stored.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @remarks If the same file already exists in the file system, then old file will be overwritten.
- * @param[in]  recorder        The handle to the media recorder
- * @param[in]  path The recording file path
+ * @param[in]  recorder    The handle to the media recorder
+ * @param[in]  path        The recording file path
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -642,7 +656,7 @@ int recorder_set_filename(recorder_h recorder, const char *path);
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @remarks You must release @a path using free().
  * @param[in]  recorder    The handle to the media recorder
- * @param[out] path    The recording file path
+ * @param[out] path        The recording file path
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -680,7 +694,7 @@ int recorder_set_file_format(recorder_h recorder, recorder_file_format_e format)
 /**
  * @brief Gets the file format for recording media stream.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in] recorder The handle to the media recorder
+ * @param[in] recorder  The handle to the media recorder
  * @param[out] format   The media file format
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
@@ -699,8 +713,8 @@ int recorder_get_file_format(recorder_h recorder, recorder_file_format_e *format
  * @since_tizen 3.0
  * @remarks You can set sound stream information including audio routing.
  *          For more details, please refer to @ref CAPI_MEDIA_SOUND_MANAGER_MODULE
- * @param[in]  recorder        The handle to the media recorder
- * @param[in]  stream_info     The sound manager info
+ * @param[in]  recorder    The handle to the media recorder
+ * @param[in]  stream_info The sound manager info
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -727,8 +741,8 @@ int recorder_set_sound_stream_info(recorder_h recorder, sound_stream_info_h stre
  * @brief Retrieves all supported file formats by invoking a specific callback for each supported file format.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @param[in] recorder  The handle to the media recorder
- * @param[in] callback The iteration callback
- * @param[in] user_data        The user data to be passed to the callback function
+ * @param[in] callback  The iteration callback
+ * @param[in] user_data The user data to be passed to the callback function
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -804,8 +818,8 @@ int recorder_get_audio_encoder(recorder_h recorder, recorder_audio_codec_e *code
  * @brief Retrieves all supported audio encoders by invoking a specific callback for each supported audio encoder.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @param[in] recorder  The handle to the media recorder
- * @param[in] callback The iteration callback
- * @param[in] user_data        The user data to be passed to the callback function
+ * @param[in] callback  The iteration callback
+ * @param[in] user_data The user data to be passed to the callback function
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -832,9 +846,9 @@ int recorder_foreach_supported_audio_encoder(recorder_h recorder, recorder_suppo
  * @brief Sets the resolution of the video recording.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @remarks This function should be called before recording (recorder_start()).
- * @param[in] recorder The handle to the media recorder
- * @param[in] width    The video width
- * @param[in] height   The video height
+ * @param[in] recorder  The handle to the media recorder
+ * @param[in] width     The video width
+ * @param[in] height    The video height
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -852,9 +866,9 @@ int recorder_set_video_resolution(recorder_h recorder, int width, int height);
 /**
  * @brief Gets the resolution of the video recording.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in] recorder The handle to the media recorder
- * @param[out] width   The video width
- * @param[out] height  The video height
+ * @param[in] recorder  The handle to the media recorder
+ * @param[out] width    The video width
+ * @param[out] height   The video height
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -878,9 +892,9 @@ int recorder_get_video_resolution(recorder_h recorder, int *width, int *height);
 /**
  * @brief Retrieves all supported video resolutions by invoking callback function once for each supported video resolution.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in] recorder The handle to the media recorder
- * @param[in] foreach_cb       The callback function to be invoked
- * @param[in] user_data        The user data to be passed to the callback function
+ * @param[in] recorder      The handle to the media recorder
+ * @param[in] foreach_cb    The callback function to be invoked
+ * @param[in] user_data     The user data to be passed to the callback function
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -950,9 +964,9 @@ int recorder_get_video_encoder(recorder_h recorder, recorder_video_codec_e *code
 /**
  * @brief Retrieves all supported video encoders by invoking a specific callback for each supported video encoder.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in] recorder The handle to the media recorder
- * @param[in] callback The iteration callback
- * @param[in] user_data        The user data to be passed to the callback function
+ * @param[in] recorder  The handle to the media recorder
+ * @param[in] callback  The iteration callback
+ * @param[in] user_data The user data to be passed to the callback function
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -978,8 +992,8 @@ int recorder_foreach_supported_video_encoder(recorder_h recorder, recorder_suppo
 /**
  * @brief Registers the callback function that will be invoked when the recorder state changes.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in] recorder The handle to the media recorder
- * @param[in] callback The function pointer of user callback
+ * @param[in] recorder  The handle to the media recorder
+ * @param[in] callback  The function pointer of user callback
  * @param[in] user_data The user data to be passed to the callback function
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
@@ -1010,9 +1024,9 @@ int recorder_unset_state_changed_cb(recorder_h recorder);
 /**
  * @brief Registers a callback function to be called when the media recorder is interrupted according to a policy.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in] recorder The handle to the media recorder
- * @param[in] callback   The callback function to register
- * @param[in] user_data   The user data to be passed to the callback function
+ * @param[in] recorder  The handle to the media recorder
+ * @param[in] callback  The callback function to register
+ * @param[in] user_data The user data to be passed to the callback function
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -1028,7 +1042,7 @@ int recorder_set_interrupted_cb(recorder_h recorder, recorder_interrupted_cb cal
 /**
  * @brief Unregisters the callback function.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in]  recorder        The handle to the media recorder
+ * @param[in]  recorder    The handle to the media recorder
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -1060,12 +1074,12 @@ int recorder_unset_interrupted_cb(recorder_h recorder);
  * @see        recorder_unset_audio_stream_cb()
  * @see        recorder_audio_stream_cb()
  */
-int recorder_set_audio_stream_cb(recorder_h recorder, recorder_audio_stream_cb callback, voiduser_data);
+int recorder_set_audio_stream_cb(recorder_h recorder, recorder_audio_stream_cb callback, void *user_data);
 
 /**
  * @brief Unregisters the callback function.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in]  recorder        The handle to the media recorder
+ * @param[in]  recorder    The handle to the media recorder
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -1076,6 +1090,39 @@ int recorder_set_audio_stream_cb(recorder_h recorder, recorder_audio_stream_cb c
  */
 int recorder_unset_audio_stream_cb(recorder_h recorder);
 
+/**
+ * @brief Registers a callback function to be called when muxed stream data is delivered.
+ * @since_tizen 4.0
+ * @remarks This callback receives the data that will be recorded, \n
+ *          but any changes to this data will not affect the recorded file.
+ * @param[in] recorder    The handle to the recorder
+ * @param[in] callback    The callback function to register
+ * @param[in] user_data   The user data to be passed to the callback function
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RECORDER_ERROR_NONE Successful
+ * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RECORDER_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #RECORDER_ERROR_INVALID_STATE Invalid state
+ * @pre        The recorder state should be #RECORDER_STATE_READY or #RECORDER_STATE_CREATED.
+ * @see        recorder_unset_muxed_stream_cb()
+ * @see        recorder_muxed_stream_cb()
+ */
+int recorder_set_muxed_stream_cb(recorder_h recorder, recorder_muxed_stream_cb callback, void *user_data);
+
+/**
+ * @brief Unregisters the callback function.
+ * @since_tizen 4.0
+ * @param[in]  recorder    The handle to the media recorder
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RECORDER_ERROR_NONE Successful
+ * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RECORDER_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #RECORDER_ERROR_INVALID_STATE Invalid state
+ * @pre        The recorder state should be #RECORDER_STATE_READY or #RECORDER_STATE_CREATED.
+ * @see        recorder_set_muxed_stream_cb()
+ */
+int recorder_unset_muxed_stream_cb(recorder_h recorder);
+
 /**
  * @brief Registers a callback function to be invoked when the recording information changes.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
@@ -1111,9 +1158,9 @@ int recorder_unset_recording_status_cb(recorder_h recorder);
 /**
  * @brief Registers the callback function to be run when reached the recording limit.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in]  recorder        The handle to media recorder
- * @param[in]  callback        The function pointer of user callback
- * @param[in]  user_data       The user data to be passed to the callback function
+ * @param[in]  recorder    The handle to media recorder
+ * @param[in]  callback    The function pointer of user callback
+ * @param[in]  user_data   The user data to be passed to the callback function
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -1151,9 +1198,9 @@ int recorder_unset_recording_limit_reached_cb(recorder_h recorder);
  *          #RECORDER_ERROR_DEVICE \n
  *          #RECORDER_ERROR_INVALID_OPERATION \n
  *          #RECORDER_ERROR_OUT_OF_MEMORY
- * @param[in]  recorder        The handle to the recorder
- * @param[in]  callback        The callback function to register
- * @param[in]  user_data       The user data to be passed to the callback function
+ * @param[in]  recorder    The handle to the recorder
+ * @param[in]  callback    The callback function to register
+ * @param[in]  user_data   The user data to be passed to the callback function
  * @return  @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -1170,7 +1217,7 @@ int recorder_set_error_cb(recorder_h recorder, recorder_error_cb callback, void
 /**
  * @brief Unregisters the callback function.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in]  recorder        The handle to the recorder
+ * @param[in]  recorder    The handle to the recorder
  * @return  @c on success, otherwise a negative error value
  * @retval    #RECORDER_ERROR_NONE Successful
  * @retval    #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -1185,8 +1232,8 @@ int recorder_unset_error_cb(recorder_h recorder);
 /**
  * @brief Gets the state of recorder device.
  * @since_tizen 3.0
- * @param[in] type The recorder type
- * @param[out] state The current state of the device
+ * @param[in]  type     The recorder type
+ * @param[out] state    The current state of the device
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -1198,9 +1245,9 @@ int recorder_get_device_state(recorder_type_e type, recorder_device_state_e *sta
 /**
  * @brief Registers a callback function to be called when the recorder device state changes.
  * @since_tizen 3.0
- * @param[in] callback The callback function to register
- * @param[in] user_data The user data to be passed to the callback function
- * @param[out] cb_id The id of the registered callback
+ * @param[in]  callback      The callback function to register
+ * @param[in]  user_data     The user data to be passed to the callback function
+ * @param[out] cb_id         The id of the registered callback
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -1332,8 +1379,8 @@ int recorder_attr_set_audio_device(recorder_h recorder, recorder_audio_device_e
 /**
  * @brief Gets the audio device for recording.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in] recorder  The handle to the media recorder
- * @param[out] device The type of an audio device
+ * @param[in]  recorder The handle to the media recorder
+ * @param[out] device   The type of an audio device
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -1347,8 +1394,8 @@ int recorder_attr_get_audio_device(recorder_h recorder, recorder_audio_device_e
 /**
  * @brief Sets the sampling rate of an audio stream.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in] recorder    The handle to the media recorder
- * @param[in] samplerate The sample rate in Hertz
+ * @param[in] recorder      The handle to the media recorder
+ * @param[in] samplerate    The sample rate in Hertz
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -1445,7 +1492,7 @@ int recorder_attr_get_video_encoder_bitrate(recorder_h recorder, int *bitrate);
  * @brief Sets the mute state of a recorder.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @param[in] recorder  The handle to the media recorder
- * @param[in] enable The mute state
+ * @param[in] enable    The mute state
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -1539,8 +1586,8 @@ int recorder_attr_set_audio_channel(recorder_h recorder, int channel_count);
 /**
  * @brief Gets the number of the audio channel.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in] recorder  The handle to the media recorder
- * @param[out] channel_count  The number of the audio channel
+ * @param[in]  recorder         The handle to the media recorder
+ * @param[out] channel_count    The number of the audio channel
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -1555,8 +1602,8 @@ int recorder_attr_get_audio_channel(recorder_h recorder, int *channel_count);
 /**
  * @brief Sets the video orientation in a video metadata tag.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in]  recorder        The handle to a media recorder
- * @param[in]  orientation     The information of the video orientation
+ * @param[in]  recorder    The handle to a media recorder
+ * @param[in]  orientation The information of the video orientation
  * @return @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
@@ -1570,8 +1617,8 @@ int recorder_attr_set_orientation_tag(recorder_h recorder,  recorder_rotation_e
 /**
  * @brief Gets the video orientation in a video metadata tag.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in]  recorder        The handle to a media recorder
- * @param[out]  orientation    The information of the video orientation
+ * @param[in]   recorder    The handle to a media recorder
+ * @param[out]  orientation The information of the video orientation
  * @return  @c 0 on success, otherwise a negative error value
  * @retval #RECORDER_ERROR_NONE Successful
  * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
index 8816d294b01c5677852ea4c18dcc99ac6950c959..f7c1a385077732367d597c2c760a19567a1ad383 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-recorder
 Summary:    A Recorder API
-Version:    0.2.49
+Version:    0.2.50
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index b799ef1d6a7cd10b21a598d5340048937a23e4b1..1b6bd7969f2bc0e538741e76f575d152bb360e19 100644 (file)
@@ -286,6 +286,50 @@ static void _recorder_client_user_callback(recorder_cb_info_s *cb_info, char *re
                        muse_core_msg_json_factory_free(send_msg);
                        break;
                }
+       case MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM:
+               {
+                       int tbm_key = 0;
+                       int size = 0;
+                       int64_t offset = 0;
+
+                       tbm_bo bo = NULL;
+                       tbm_bo_handle bo_handle = {.ptr = NULL};
+                       char *send_msg = NULL;
+
+                       muse_recorder_msg_get(tbm_key, recv_msg);
+                       if (tbm_key == 0) {
+                               LOGE("invalid key");
+                               break;
+                       }
+
+                       if (!_recorder_import_tbm_key(cb_info->bufmgr, tbm_key, &bo, &bo_handle)) {
+                               LOGE("tbm key %d import failed", tbm_key);
+                               break;
+                       }
+
+                       muse_recorder_msg_get(size, recv_msg);
+                       muse_recorder_msg_get(offset, recv_msg);
+
+                       ((recorder_muxed_stream_cb)cb_info->user_cb[event])((void *)bo_handle.ptr,
+                               size, (unsigned long long)offset, cb_info->user_data[event]);
+
+                       /* release imported bo */
+                       _recorder_release_imported_bo(&bo);
+
+                       /* return buffer */
+                       send_msg = muse_core_msg_json_factory_new(MUSE_RECORDER_API_RETURN_BUFFER,
+                               MUSE_TYPE_INT, "tbm_key", tbm_key, NULL);
+                       if (send_msg) {
+                               if (muse_core_ipc_send_msg(cb_info->fd, send_msg) <= 0)
+                                       LOGE("sending message failed");
+
+                               muse_core_msg_json_factory_free(send_msg);
+                               send_msg = NULL;
+                       } else {
+                               LOGE("failed to create send msg for key %d", tbm_key);
+                       }
+                       break;
+               }
        case MUSE_RECORDER_EVENT_TYPE_ERROR:
                {
                        int error = 0;
@@ -2186,7 +2230,7 @@ int recorder_set_sound_stream_info(recorder_h recorder, sound_stream_info_h stre
 }
 
 
-int recorder_set_state_changed_cb(recorder_h recorder, recorder_state_changed_cb callback, voiduser_data)
+int recorder_set_state_changed_cb(recorder_h recorder, recorder_state_changed_cb callback, void *user_data)
 {
        int ret = RECORDER_ERROR_NONE;
        recorder_cli_s *pc = (recorder_cli_s *)recorder;
@@ -2199,11 +2243,13 @@ int recorder_set_state_changed_cb(recorder_h recorder, recorder_state_changed_cb
 
        LOGD("Enter, handle :%x", pc->remote_handle);
 
-       pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE] = callback;
-       pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE] = user_data;
-
        _recorder_msg_send(api, pc->cb_info, &ret);
 
+       if (ret == RECORDER_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE] = callback;
+               pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE] = user_data;
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
@@ -2225,6 +2271,11 @@ int recorder_unset_state_changed_cb(recorder_h recorder)
 
        _recorder_msg_send(api, pc->cb_info, &ret);
 
+       if (ret == RECORDER_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE] = NULL;
+               pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE] = NULL;
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
@@ -2244,11 +2295,13 @@ int recorder_set_interrupted_cb(recorder_h recorder, recorder_interrupted_cb cal
 
        LOGD("Enter, handle :%x", pc->remote_handle);
 
-       pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED] = callback;
-       pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED] = user_data;
-
        _recorder_msg_send(api, pc->cb_info, &ret);
 
+       if (ret == RECORDER_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED] = callback;
+               pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED] = user_data;
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
@@ -2270,13 +2323,18 @@ int recorder_unset_interrupted_cb(recorder_h recorder)
 
        _recorder_msg_send(api, pc->cb_info, &ret);
 
+       if (ret == RECORDER_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED] = NULL;
+               pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED] = NULL;
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
 }
 
 
-int recorder_set_audio_stream_cb(recorder_h recorder, recorder_audio_stream_cb callback, voiduser_data)
+int recorder_set_audio_stream_cb(recorder_h recorder, recorder_audio_stream_cb callback, void *user_data)
 {
        int ret = RECORDER_ERROR_NONE;
        recorder_cli_s *pc = (recorder_cli_s *)recorder;
@@ -2289,11 +2347,13 @@ int recorder_set_audio_stream_cb(recorder_h recorder, recorder_audio_stream_cb c
 
        LOGD("Enter, handle :%x", pc->remote_handle);
 
-       pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM] = callback;
-       pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM] = user_data;
-
        _recorder_msg_send(api, pc->cb_info, &ret);
 
+       if (ret == RECORDER_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM] = callback;
+               pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM] = user_data;
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
@@ -2315,6 +2375,63 @@ int recorder_unset_audio_stream_cb(recorder_h recorder)
 
        _recorder_msg_send(api, pc->cb_info, &ret);
 
+       if (ret == RECORDER_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM] = NULL;
+               pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM] = NULL;
+       }
+
+       LOGD("ret : 0x%x", ret);
+
+       return ret;
+}
+
+
+int recorder_set_muxed_stream_cb(recorder_h recorder, recorder_muxed_stream_cb callback, void *user_data)
+{
+       int ret = RECORDER_ERROR_NONE;
+       recorder_cli_s *pc = (recorder_cli_s *)recorder;
+       muse_recorder_api_e api = MUSE_RECORDER_API_SET_MUXED_STREAM_CB;
+
+       if (!pc || !pc->cb_info || !callback) {
+               LOGE("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
+               return RECORDER_ERROR_INVALID_PARAMETER;
+       }
+
+       LOGD("Enter, handle :%x", pc->remote_handle);
+
+       _recorder_msg_send(api, pc->cb_info, &ret);
+
+       if (ret == RECORDER_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM] = callback;
+               pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM] = user_data;
+       }
+
+       LOGD("ret : 0x%x", ret);
+
+       return ret;
+}
+
+
+int recorder_unset_muxed_stream_cb(recorder_h recorder)
+{
+       int ret = RECORDER_ERROR_NONE;
+       muse_recorder_api_e api = MUSE_RECORDER_API_UNSET_MUXED_STREAM_CB;
+       recorder_cli_s *pc = (recorder_cli_s *)recorder;
+
+       if (!pc || !pc->cb_info) {
+               LOGE("NULL handle");
+               return RECORDER_ERROR_INVALID_PARAMETER;
+       }
+
+       LOGD("ENTER");
+
+       _recorder_msg_send(api, pc->cb_info, &ret);
+
+       if (ret == RECORDER_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM] = NULL;
+               pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM] = NULL;
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
@@ -2334,11 +2451,13 @@ int recorder_set_error_cb(recorder_h recorder, recorder_error_cb callback, void
 
        LOGD("Enter, handle :%x", pc->remote_handle);
 
-       pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_ERROR] = callback;
-       pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_ERROR] = user_data;
-
        _recorder_msg_send(api, pc->cb_info, &ret);
 
+       if (ret == RECORDER_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_ERROR] = callback;
+               pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_ERROR] = user_data;
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
@@ -2360,13 +2479,18 @@ int recorder_unset_error_cb(recorder_h recorder)
 
        _recorder_msg_send(api, pc->cb_info, &ret);
 
+       if (ret == RECORDER_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_ERROR] = NULL;
+               pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_ERROR] = NULL;
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
 }
 
 
-int recorder_set_recording_status_cb(recorder_h recorder, recorder_recording_status_cb callback, voiduser_data)
+int recorder_set_recording_status_cb(recorder_h recorder, recorder_recording_status_cb callback, void *user_data)
 {
        int ret = RECORDER_ERROR_NONE;
        recorder_cli_s *pc = (recorder_cli_s *)recorder;
@@ -2379,11 +2503,13 @@ int recorder_set_recording_status_cb(recorder_h recorder, recorder_recording_sta
 
        LOGD("Enter, handle :%x", pc->remote_handle);
 
-       pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS] = callback;
-       pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS] = user_data;
-
        _recorder_msg_send(api, pc->cb_info, &ret);
 
+       if (ret == RECORDER_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS] = callback;
+               pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS] = user_data;
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
@@ -2405,13 +2531,18 @@ int recorder_unset_recording_status_cb(recorder_h recorder)
 
        _recorder_msg_send(api, pc->cb_info, &ret);
 
+       if (ret == RECORDER_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS] = NULL;
+               pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS] = NULL;
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
 }
 
 
-int recorder_set_recording_limit_reached_cb(recorder_h recorder, recorder_recording_limit_reached_cb callback, voiduser_data)
+int recorder_set_recording_limit_reached_cb(recorder_h recorder, recorder_recording_limit_reached_cb callback, void *user_data)
 {
        int ret = RECORDER_ERROR_NONE;
        recorder_cli_s *pc = (recorder_cli_s *)recorder;
@@ -2422,11 +2553,13 @@ int recorder_set_recording_limit_reached_cb(recorder_h recorder, recorder_record
                return RECORDER_ERROR_INVALID_PARAMETER;
        }
 
-       pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED] = callback;
-       pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED] = user_data;
-
        _recorder_msg_send(api, pc->cb_info, &ret);
 
+       if (ret == RECORDER_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED] = callback;
+               pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED] = user_data;
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
@@ -2448,6 +2581,11 @@ int recorder_unset_recording_limit_reached_cb(recorder_h recorder)
 
        _recorder_msg_send(api, pc->cb_info, &ret);
 
+       if (ret == RECORDER_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED] = NULL;
+               pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED] = NULL;
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
index ed9ec3c4b61d21d3fba6073eb0bddd14aab7a1d6..e08cadd3737bb6be7d3ed50327d3800f05f9be66 100644 (file)
@@ -100,6 +100,7 @@ static int g_recorder_device_changed_cb_id;
 #define TARGET_FILENAME_PATH            "/opt/usr/home/owner/media/Sounds/"
 #define TARGET_FILENAME_VIDEO           TARGET_FILENAME_PATH"test_rec_video.mp4"
 #define TARGET_FILENAME_AUDIO           TARGET_FILENAME_PATH"test_rec_audio.m4a"
+#define TARGET_FILENAME_MUXED_CB        TARGET_FILENAME_PATH"muxed_stream_cb.mp4"
 
 #define AUDIO_SOURCE_SAMPLERATE_AAC     44100
 #define AUDIO_SOURCE_SAMPLERATE_AMR     8000
@@ -276,6 +277,13 @@ static void _state_changed_cb(recorder_state_e previous_state, recorder_state_e
        return;
 }
 
+static void _interrupted_cb(recorder_policy_e policy, recorder_state_e previous_state, recorder_state_e current_state, void *user_data)
+{
+       g_print("\nrecorder interrupted callback called [state %d -> %d, policy %d]\n",
+               previous_state, current_state, policy);
+       return;
+}
+
 static void _recorder_device_state_changed_cb(recorder_type_e type, recorder_device_state_e state, void *user_data)
 {
        g_print("\nrecorder device[%d] state changed to %d\n", type, state);
@@ -308,6 +316,40 @@ static void _recording_limit_reached_cb(recorder_recording_limit_type_e type, vo
        return;
 }
 
+static void _recording_muxed_stream_cb(void *stream, int size, unsigned long long offset, void *user_data)
+{
+       static unsigned long long current_offset = 0;
+
+       FILE *fp = NULL;
+
+       g_print("\tRECORDING MUXED STREAM CB - %p, size %d, offset %llu\n", stream, size, offset);
+
+       if (stream && size > 0) {
+               if (access(TARGET_FILENAME_MUXED_CB, F_OK))
+                       fp = fopen(TARGET_FILENAME_MUXED_CB, "w");
+               else
+                       fp = fopen(TARGET_FILENAME_MUXED_CB, "rb+");
+
+               if (fp) {
+                       if (current_offset > offset) {
+                               g_print("\tback to %llu\n", offset);
+                       }
+
+                       fseeko(fp, (off_t)offset, SEEK_SET);
+
+                       fwrite(stream, 1, size, fp);
+                       fclose(fp);
+                       fp = NULL;
+               } else {
+                       g_print("\n\n\t File open failed [%s], errno %d", TARGET_FILENAME_MUXED_CB, errno);
+               }
+
+               current_offset = offset;
+       }
+
+       return;
+}
+
 
 static inline void flush_stdin()
 {
@@ -434,7 +476,8 @@ static void print_menu()
                        g_print("\t  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [etc]\n");
                        g_print("\t     's' Strobe (Flash) \n");
                        g_print("\t     'z' Video-stabilization \n");
-                       g_print("\t     'm' Camcorder Motion Rate setting \n");
+                       g_print("\t     'M' Camcorder Motion Rate setting \n");
+                       g_print("\t     'm' Set/Unset muxed stream callback \n");
                        g_print("\t     'b' back\n");
                        g_print("\t=======================================\n");
                } else {
@@ -448,6 +491,7 @@ static void print_menu()
                        g_print("\t     '5' Samplerate \n");
                        g_print("\t     '6' Channel \n");
                        g_print("\t     '7' Encoder bitrate \n");
+                       g_print("\t     'm' Set/Unset muxed stream callback \n");
                        g_print("\t     'b' back\n");
                        g_print("\t=======================================\n");
                }
@@ -910,7 +954,7 @@ static void setting_menu(gchar buf)
                        }
                        break;
 
-               case 'M':
+               case 'M': /* Setting > Camcorder Motion-rate */
                        g_print("*Camcorder Motion Rate setting! (should be bigger than zero)\n");
 
                        flush_stdin();
@@ -920,6 +964,22 @@ static void setting_menu(gchar buf)
                        result = recorder_attr_set_recording_motion_rate(hcamcorder->recorder, motion_rate);
                        break;
 
+               case 'm': /* Setting > muxed stream callback */
+                       g_print("* Muxed stream callback\n");
+
+                       flush_stdin();
+
+                       g_print("[set(1)/unset(2)] : ");
+
+                       err = scanf("%d", &idx);
+
+                       if (idx == 1)
+                               result = recorder_set_muxed_stream_cb(hcamcorder->recorder, _recording_muxed_stream_cb, NULL);
+                       else if (idx == 2)
+                               result = recorder_unset_muxed_stream_cb(hcamcorder->recorder);
+                       else
+                               result = RECORDER_ERROR_INVALID_PARAMETER;
+
                case 'b': /* back */
                        hcamcorder->menu_state = MENU_STATE_MAIN;
                        break;
@@ -1015,6 +1075,22 @@ static void setting_menu(gchar buf)
                        result = recorder_attr_set_audio_encoder_bitrate(hcamcorder->recorder, bitrate);
                        break;
 
+               case 'm': /* Setting > muxed stream callback */
+                       g_print("* Muxed stream callback\n");
+
+                       flush_stdin();
+
+                       g_print("[set(1)/unset(2)] : ");
+
+                       err = scanf("%d", &idx);
+
+                       if (idx == 1)
+                               result = recorder_set_muxed_stream_cb(hcamcorder->recorder, _recording_muxed_stream_cb, NULL);
+                       else if (idx == 2)
+                               result = recorder_unset_muxed_stream_cb(hcamcorder->recorder);
+                       else
+                               result = RECORDER_ERROR_INVALID_PARAMETER;
+
                case 'b': /* back */
                        hcamcorder->menu_state = MENU_STATE_MAIN;
                        break;
@@ -1191,6 +1267,7 @@ static gboolean init(int type)
 
        recorder_set_error_cb(hcamcorder->recorder, _recorder_error_cb, NULL);
        recorder_set_state_changed_cb(hcamcorder->recorder, _state_changed_cb, NULL);
+       recorder_set_interrupted_cb(hcamcorder->recorder, _interrupted_cb, NULL);
        recorder_set_recording_status_cb(hcamcorder->recorder, _recording_status_cb, NULL);
        recorder_set_recording_limit_reached_cb(hcamcorder->recorder, _recording_limit_reached_cb, NULL);
 
@@ -1214,13 +1291,14 @@ static gboolean init_handle()
        return TRUE;
 }
 
-
+#ifdef USE_SOUND_STREAM_INFO
 static void _sound_stream_focus_state_changed_cb(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_e focus_state,
        sound_stream_focus_change_reason_e reason_for_change, int sound_behavior, const char *additional_info, void *user_data)
 {
        g_print("focus changed : reason %d\n", reason_for_change);
        return;
 }
+#endif /* USE_SOUND_STREAM_INFO */
 
 /**
  * This function is to change camcorder mode.
@@ -1314,6 +1392,7 @@ static gboolean mode_change(gchar buf)
                        return FALSE;
                }
 
+#ifdef USE_SOUND_STREAM_INFO
                {
                        sound_stream_info_h stream_info = NULL;
 
@@ -1323,6 +1402,7 @@ static gboolean mode_change(gchar buf)
                                sound_manager_destroy_stream_information(stream_info);
                        }
                }
+#endif /* USE_SOUND_STREAM_INFO */
 
                err = recorder_attr_set_audio_device(hcamcorder->recorder, RECORDER_AUDIO_DEVICE_MIC);
                if (err != RECORDER_ERROR_NONE) {